boot3/Toolbox/FontMgr/FontMgr.a

5483 lines
219 KiB
Plaintext
Raw Normal View History

;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;
; File: FontMgr.a
;
; Copyright: <09> 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):
;
; <SM23> 7/6/93 kc Roll in Ludwig.
; <LW2> 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<6F>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.
; <SM22> 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.
; <SM21> 5/27/93 CSS Roll out <71> from previously rolled in from Reality because it
; was rejected in the Cyclone code review.
; <SM20> 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<6F>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.
; <SM19> 11/19/92 RB Set ROMMapInsert to MapTrue just before doing some GetResource
; calls so that we look in ROM first.
; <SM18> 11/12/92 PN Get rid of <20> 020 conditionals
; <SM17> 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 <csd>: I<>ll get it right one of these days<79> If we<77>re
; remembering an alternate font and we determine that we<77>ve
; already picked up an alternate, don<6F>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 <BBM>: #1039692 <BBM>: 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 <gbm>: The last change had a bug which caused an
; infinite loop if QuickDraw wants a size that doesn<73>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 <gbm>: 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 <pvh>: Locking the candidate list while I<>m walking
; through it in RealFont would be nice<63>
; <59> 7/11/92 DTY #1035746 <gbm>: In GetBestFONDForSizeAndStyle, mark the
; candidate 'FOND' non-purgeable so it doesn<73>t get purged when a
; large TrueType font is loaded.
; <58> 7/8/92 DTY #1035322 <csd>: 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 <pvh>: 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<73>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 <FM>: 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<77>ve got a TrueType font, don<6F>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<77>re talking about Macintosh developers here, who are a
; breed apart and there<72>s always ONE person that doesn<73>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 <csd>: 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<6F>t care about that at this point.
; <46> 4/24/92 DTY Case Obj sucks. Don<6F>t use Case Obj for ROM builds.
; <45> 4/24/92 DTY TrueType<70> lives! Remove all the hasSplineFonts and Gaudi
; conditionals.
; <44> 3/31/92 DTY #1024665,<FM>: Change all the one deep Resource Manager calls
; back to the n deep ones since we<77>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<69>s much easier to
; read and understand.#1025041,<pvh>: Improve
; GetFONDForSizeAndStyle so it<69>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<57>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<6F>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<65>s derefence the TrueType global handle before we use it<69>
; <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<6F>t call
; MakeMapOneDeep in LoadSplineResource, since LoadSplineResource
; is called from other places in the code that don<6F>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<73>t restore D4 and D5 if a
; font wasn<73>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<73>t a real good solution.
; <21> 10/23/91 DTY Brian lied. The Resource Manager doesn<73>t stop at SysMapHndl.
; Stop slamming TopMapHndl to get around what doesn<73>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<73>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<6F>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<64>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<61>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<64>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 <cr> to zero,
; inorder to make FractEnable on/off widths consistant between
; bitmaps and outlines.
; <7> 1/8/91 CL (GM) In the RealFont routine<6E> 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<70> 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<61>s
; it?!?)
; <11> 7/16/90 CL FMExist does not exist on the MacPlus so it can<61>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<5A> 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<5A> 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<61>
; <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,
; <<3C>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
; <<3C>2.9> 5/5/89 CEL Moved label outside of conditionals so system would build,
; <<3C>2.8> 5/4/89 CEL Cleaned up conditionals for ROM
; <<3C>2.7> 5/3/89 CEL Bass rolled into ROM. NOTE:Spline Fonts are conditionalized
; <<3C>2.5> 5/1/89 cel Rolled in Bass<73>
; <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.
; <<3C>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.
; <PB164> 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 <20>not<6F> srcBic modes, look for second
; best multibit font, don<6F>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<65>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
; <C206> 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
;
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BLANKS ON
STRING ASIS
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; Check Defines<65>
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
IF (&TYPE('HAS_COLOR') = 'UNDEFINED') THEN
HAS_COLOR EQU hasCQD
ENDIF
IF (&TYPE('forJP') = 'UNDEFINED') THEN
forJP EQU 0
ENDIF
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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' ; <C206><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 <BAL 08May88> @@@@
;
; 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 | <20><><EFBFBD><EFBFBD>normal QuickDraw style byte<74><65><EFBFBD> <BAL 08May88> @@@@
;
; 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)
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; PROCEDURE InitFonts -- initialize the font manager data structures
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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<6F>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; Moved in from BassCommTail (now part of BassPatches)
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if HAS_COLOR then
GetDevPix
else
BWGetDevPix
endif
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<6F>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<6F>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<64>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<6F>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 <DLD 24-Oct-85>
CMP.L SpExtra(A0),D0 ; did it change? <DLD 24-Oct-85>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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).
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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>
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<6F>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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.
;
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;
; 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.
;
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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<6C>
; 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<73>t a nonpurged entry then we<77>re out of luck; don<6F>t use cache.
; if a memory allocation call fails, then the system heap is in bad shape; don<6F>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.
;
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<6F>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<64>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<6F>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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. <SM22>
; This doesn't work so well because Cyclone changes ScrnBase on depth switch <SM22>
; without updating the QuickDraw Globals. A "More Correct" fix would be to <SM22>
; have the process manager update the QuickDraw Globals of all running processes. <SM22>
MOVE.L ScrnBase,D0 ; get pointer to screen base address <SM22>
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 <BAL 09May88> @@@@
@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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<6F>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LookForColor
BFFFO D6{$1A,6},D6 ; turns 32, 16, 8, 4, 2, 1 into $1A, $1B, $1C, $1D, $1E, $1F <BAL 08May88> @@@@
NOT D6 ; $FFE5 <20><>$FFE0
AND #7,D6 ; 5, 4, 3, 2, 1, 0 (amount to shift to multiply by bit depth) <BAL 08May88> @@@@
; 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 <20>not<6F> 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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<6F>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<6F>t worry about 1 bit; it has already been found. And it can<61>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? <BAL 08May88> @@@@ 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<6F>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 <BAL 08May88> @@@@ 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<6F>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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 <SM19> 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 <CEL-16>
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 <CEL-16>
AND #$7,D3 ; 0 <20> 5 (bit depth of 1 <20> 32) <CEL-16>
cmp #3,d6 ; is output depth <= 8 bits/pixel? <CEL-17>
ble.s @depthOK ; use the original font <CEL-17>
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 <BAL/JDB 07Jul88>
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><BAL/JDB 07Jul88>
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 <20> 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 <BAL 08May88> 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<73>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<6F>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 <20> 5 into 1 <20> 32 <BAL 08May88> @@@@
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 <20> 32) <BAL 08May88> @@@@
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 <BAL 09May88> @@@@
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<61>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<64>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 <20>synthetic<69> font via font flag
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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<61>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<69>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<6F>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<77>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TST.B FractEnable ; fractional widths? <06Nov85>
BNE.S MakeWTab ; yes, then don<6F>t use the rounded result.
MOVE.B D0,FOutExtra ; and save the byte-sized result <BAL/NMB 07Sep88>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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 = <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> * <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> * 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>
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; _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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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
; <FOND,D3> 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<65>
CMP.B #-1,FontFlag
BEQ Pop6SubFont ; if so, go start over.
MOVE.W D3,FONDID ; moved these two lines from above <DLD,8-19-85>
MOVE.L A0,LastFOND ; so we will cache when no FOND. <DLD,8-19-85>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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<6F>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<6F>t load it into memory, but create an empty
; handle for it in it<69>s resource reference entry. We can probably get rid of the call to
; ReleaseResource and the zone mucking, since it<69>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<69>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<EFBFBD>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;
; 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.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<64>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 <SM19> 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<6F>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<64>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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: <20>
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
FindSize
tst.l (a2) ; See if it<69>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) <JH because of change below this can't be a short branch anymore>
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<73>t available. It returns the plain style of the requested size
; if the desired style isn<73>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<6F>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<69>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<73>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<61>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<49>s not plain
tst.l d7 ; <58> See if we<77>ve already remembered a plain TrueType font
bnz.s @gotPlainSpline ; <58> We<57>ve already got one, so don<6F>t remember this new one
move.l a4,d7 ; It<49>s plain. Remember this cache entry in case the right bitmap size isn<73>t found.
@gotPlainSpline
tst.w d2 ; Did we want plain?
bne.s @keepLooking ; Nope. Keep looking
bra.s @checkSplinePreferred ; Yes. See if it<69>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<73>t have the desired style.
swap d0 ; <63> Check the desired style to see if we<77>re trying to get plain
tst.w d0 ; <63> If we<77>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<57>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<49>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<77>ve got an alternate plain bitmap
bnz.s @gotPlainBitmap ; <58> If we do, don<6F>t save this new one.
move.l a4,d6 ; Remember this cache entry as the plain base in case the desired style isn<73>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<69>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<73>t have the desired style.
swap d0 ; <63> Check the desired style to see if we<77>re trying to get plain
tst.w d0 ; <63> If we<77>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<6F>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<73>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<57>ve got a style alternate. Return that.
bra.s @setupForLoad ; <67> Return the styled bitmap.
; The plain bitmap wasn<73>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<73>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<57>ve got a TrueType version. Go use it.
; A plain spline couldn<64>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<64>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<6F>t infinite loop if there is no styled alternate
; either.
swap d3 ; <64>
move.w #1,d3 ; <64> Pretend we<77>re looking for a style so we don<6F>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<57>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<6F>t let it get purged while we<77>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<61>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<64>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<72>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<73>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<57>ve found the right map. Now check out the font assocation table entries.
move.l a3,d1 ; <54> See if we<77>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<64>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<77>re
; talking about Macintosh developers here, who are a breed apart and there<72>s always ONE
; person that doesn<73>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<77>re done
tst.b 3(a1) ; <49> Check in case we have a FOND that doesn<73>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<77>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<64>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<64>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<64>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<6F>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 <DLD-12-Sep-85>
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<61>t find a font, then
beq.s NewFailedRestore ; <36> we<77>re REALLY hosed!
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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<77>re coming from FoundTheSize
MOVE D5,-(SP) ; put size on stack
MOVE (A3),D3 ; get the requested family
BRA OldFontLookUp
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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
;
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <20>null<6C> 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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<61>t see any trivial way of
; >> rolling them together. For one, all registers are used.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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<6F>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<6F>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <SM19> 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<73>t.
subq #4,sp
move.w d1,-(sp)
clr.w -(sp) ; Don<6F>t use the application font if font family isn<73>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<69>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<57>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<6F>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<69>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<77>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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; 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<61>s table.
LeftMask EQU $20 ; position of left masks in QuickDraw<61>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 <BAL 08May88> @@@@ 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
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
; getIs32Bit - load the is32Bit flag from the splineKey globals.
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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>
;*******************************************************************
;*******************************************************************
;*******************************************************************