mac-rom/QuickDraw/DrawText.a

5690 lines
223 KiB
Plaintext

;
; File: DrawText.a
;
; Contains: QuickDraw Character Generator
;
; Copyright: © 1983-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM6> 9/12/93 SAM Changed all instances of _Translate24to32 to _rTranslate24to32
; so they can conditionalized out of the build.
; <SM5> 5/21/93 CSS Fix some things with hasDoubleByte.
; <SM4> 8/28/92 CSS Update from Reality:
; <77> 8/21/92 csd Reentered fix <76> since the file got messed up with garbage
; data when it was checked in.
; <76> 8/21/92 DTY #1039679 <JH>: #1039679 <JH>: Underlining TrueType characters
; would overrun the width of the string due to some code added for
; double byte TrueType support. This new code adds some slop to
; the rectangle that QuickDraw draws text into. When QuickDraw
; goes to underline the text, it draws a line the width of this
; rectangle, which is wider than the width of the text, because of
; this extra slop. Added a check to not add this slop if weÕre not
; drawing with a double byte TrueType font. This returns the code
; path to what it was under 7.0, while leaving the code path there
; for double byte TrueType fonts.
; <SM3> 7/16/92 CSS Update from Reality:
; <75> 6/8/92 SAH #1031825: Changed way the multColor flag is passed to
; StretchBits. Bit 0 now means the source is black and white only.
; Bit 1 means the source contains colour (not used).
; <74> 4/24/92 DTY Case Obj still sucks. Put the spline font conditionals back in
; until I can get this stupid case sensitivity stuff worked out so
; the ROM keeps building.
; <73> 4/24/92 DTY DonÕt INCLUDE anything except for SysPrivateEqu.a and
; LinkedPatchMacros.a for ROM builds, since this file is included
; into CQD.a.
; <72> 4/24/92 DTY Remove all Spline_Fonts conditionals.
; <SM2> 4/16/92 PN Include the right files for ROM build, BigJSR. Eliminated
; has_color condition and 68000 condition (SuperMario will always
; run with colorQD and >68000)
; <71> 9/27/91 JSM DonÕt define hasDoubleByte for ROM builds.
; <70> 9/25/91 jlf Rolled in Pacific TrueType modifications and removed
; DOUBLE_BYTE conditional code. New doublebyte code is
; bracketed with hasDoubleByte conditional.
; <69> 7/10/91 JSM Remove obsolete SysVers conditionals.
; <68> 6/12/91 LN added #include 'SysPrivateEqu.a'
; <67> 4/30/91 dba move GWorldFlag equate inside PROC to get rid of warning
; <66> 3/27/91 KON MRR,gbm, WRKSHT#TitleBugTriggered: Colorized OR text mode to
; 1-bit source with bass font goes through text blit loop which
; does not know how to colorize OR mode. The fix is to force the
; drawing through stretch if going to 1-bit and the foreground
; color is not black.
; <65> 2/28/91 CL (KON)(RB)#82681 related bug. Need to make cache non purgeable
; during the memory call for offscreen text and then restore the
; state.
; <64> 1/18/91 CL (RB)Making the getmasktable conditional consistent with the
; original. Setting to NOT HAS_COLOR instead of NOT NOT_68000.
; This will fix the Mac32 build.
; <63> 1/16/91 gbm (csd) Fix total screwup by Chaz and KON. Checking in files that
; will NOT assemble is a heinous crime. Do it again, and itÕs off
; to Saudi Arabia...
; <62> 1/16/91 CL (KON)Moving call to getmasktable from the inner blit loop to the
; set up instead. Setting it up on the stack.
; <61> 1/15/91 CL (MR)Now safecount must be set to -2 if the pen loc needs to be
; added inside of stdtxmeas.
; <60> 1/14/91 SMB (jdt) Removing initialization of overflow count since added to
; StdTxMeas.
; <59> 1/9/91 RB (CEL/PKE/GM/DA) Fixing long string overflow bug by truncating
; the count.
; <58> 12/13/90 CL (RB) Left overhang calculation did not work correctly unless the
; glyph was cached. A soft error of no_bits occured and the left
; overhang was skipped.
; <57> 12/13/90 CL (RB)In the deepChar blit loops when a character has no bitmap the
; pin needed to be advanced.
; <56> 11/27/90 CL (SMC) GC card cached the offscreen gworld. Must get and use the
; gc card cache addr.
; <55> 11/8/90 KON Call stretchbits trap for B&W machines if 7.0. [CEL]
; <54> 10/22/90 CL (BKR)Adding minimum memory mode to band characters and support
; minimum cache sizes. (SMC)Added in optimization for blit
; expansion loops.
; <53> 10/10/90 CL Adding call to preflight routine when banding to make sure we
; can get enough memory for the banded character.
; <52> 10/8/90 CL When figuring out how much space was needed for the offscreen
; buffer an ext.l was used to a unsigned word which turned into a
; negative number. Bad news! Not enough memory would be allocated
; and the heap got corrupted. Now a moveq before is used to clear
; the long.
; <50> 10/1/90 CL Added check to make sure the cache got loaded by the FontMgr.
; <49> 9/21/90 CL (BAL) A bug was introduced in the charextra code that treated
; chExtra as a unsigned character. It did a asl.l on a negative
; value making the space tremendous. An ext.l fixes the problem.
; <48> 9/18/90 CL No longer calling sbSearchForCache everytime since the
; fontMgr should load the cache in everytime
; <47> 9/17/90 BG Removed <29>, <33> and <38>. 040s are now behaving more
; reliably.
; <46> 9/4/90 CL Memory model changed a little for the cachehandle. The cacheHandle
; could change when a sbretrieveglyph call is made since it may place
; the block in another heap. So after call is made, re-init the cachehand
; via the splinekey. sb_shrinkbitmap is no longer called for cached contours
; so the bytewidth must be retrieved from the stack after calling the
; sbretrieveglyph call. No longer using the tempbitmapHand so
; there is no need for the check to dispose.
; <45> 8/27/90 RB A branch to decCount caused a warning since decCount is right
; next store and it turns to a NOP. Got rid of branch.
; <44> 8/24/90 CL Added back in changes in <39> version with bug fix to make sure
; the dither flag go set up. Also made 16 and 32 bit fonts work by
; making sure a color table was really truely pointed to by the
; source pixmap.
; <43> 8/24/90 PKE (per JT) Use new Script Mgr line layout values in GrafGlobals
; instead of soon-to-be-obsolete values in Script Mgr globals.
; <42> 8/18/90 RB Temporarily revert to version 38 so fonts work at all sizes
; again.
; <41> 8/18/90 RB Many sizes don't render to the screen
; <40> 8/17/90 gbm fix a warning about branching to the next instruction
; <39> 8/16/90 CL Color Fonts just didnÕt work! First of all the Font DA/Mover
; never moved 'fctb's. Voila, no color. DrText assumed a 1 bit
; font to create the mask but could get a 2, 4, or 8 bit font.
; This created a bad mask. When shrinking the bits from a greater
; pointsize, text looked really bad. So on depths greater than one
; and we are shrinking, we use the Dither mode which looks pretty
; darn good.
; <38> 8/15/90 BG Found another place for an EclipseNOP.
; <37> 7/31/90 PKE (really CL on PKEÕs machine) Needed to scale D3 value of the
; char code when the glyph does not exist. This caused an address
; error.
; <36> 7/30/90 CL Somehow the descent kerning adjustment code got deletedÉ So I am
; adding it back in.
; <35> 7/27/90 CL Needed to add cmpSize to the color pixmap.
; <34> 7/26/90 gbm change noCache to noCaching to avoid assembly conflict, collapse
; two conditional blocks together
; <33> 7/20/90 BG Found another place that an EclipseNOP was needed.
; <32> 7/20/90 DTY Bass: The Linked Patch. Changed loads of junk to make Bass work
; as a linked patch. Added conditional black and white procedure
; names, since weÕre effectively carrying around two copies of
; DrawText in Bass, and we need to keep the procedure names
; unique. Also added check for Bass_Init for code that gets
; compiled when hasSplineFonts is true, since hasSplineFonts is
; not true when building Gaudi for System 6.0.x. Changed jumps
; into ROM to use the jmpROM macro.
; <31> 7/17/90 CL Did not need to call swapmmumode while going offscreen.
; <30> 6/29/90 CL Always calling sb_searchforcache to insure correct font cache is
; loaded for blitting.
; <29> 6/26/90 BG Rolled in 040-related changes.
; <28> 6/25/90 CL fontPrivate should only be included in this file when it is a
; splinefont build.
; <27> 6/22/90 CL Fixed up include files to use new fontPrivate.a, toolEqu.a and
; qdhooks.
; <26> 6/20/90 KON Despite the intials on this comment, JT fixed a bug in the
; character extra calculations. I was using the wrong register to
; find the current GrafPort, so the chExtra value for new ports
; was incorrect. This led to interesting, but potentially
; disasterous layout of text.
; <25> 6/18/90 CL Fixed Outline Font Clipping bug on the 68000 class machines.
; <24> 6/13/90 CL Fixing Outline & Italic Horizontal clipping bug.
; <23> 6/12/90 JT Got loose with the kerning adjustment. We now keep both the
; kerning adjustment for the pen and a separate kerning bounds for
; the left edge of the off-screen bit image that is then copied to
; the screen. The kerning adjustment for the pen works as before
; (the full fKernMax is used) but the kerning bounds for the
; offscreen bit image only includes that part of the first
; character in the string that actually kerns. I add the offset of
; the first character to the fKernMax and pin the value at zero to
; calculate the kerning bounds. All this only applies to bitmap
; fonts.
; <22> 6/12/90 JT Added alternate code for keeping the width fraction when scaling
; a bitmap font. This code replaces the nasty fixed-point trap
; routines mentioned in the previous comment.
; <21> 6/9/90 JT Removed some active and some commented out debugging traps. Also
; removed all commented out references to the old 32-bit flags.
; Sorry Chazz, I just couldn't help myself.
; <20> 6/9/90 JT Late-night session yields all kinds of interesting changes.
; First, the CalcCharExtra routine has been moved here from Text.a
; since it is now used by both the classic and the color versions
; of QuickDraw. Second, the classic version of QuickDraw now uses
; the fixed-point result of a StdTxMeas call by looking at the
; fontAdj value in the QuickDraw globals. It used to use the
; integer value that was returned as the result of the StdTxMeas
; call. Third, there is a big hack in the bitMap stretching code
; where we scale the width of the text by the horizontal numerator
; and denominator. For 68020 machines we use the double-register
; multiply and divide routines to properly scale the fixed-point
; text width by the integer numerator and denominator. But for
; 68000 machines we just toss the fractional part of the width and
; use standard single-register multiply and divide routines to do
; the scaling. As a result, stretched drawing results in truncated
; pen motions. That is, the fractional part of the pen motion is
; lost if we are drawing on an old machine and we do not have a
; font strike for the requested size and scaling parameters.
; Anyway, I put in a hack to use the fixed-point trap routines to
; do the correct scaling, but I think this probably causes some
; (don't laugh) performace degradation. Some arithmetic god should
; look into this.
; <19> 6/9/90 JT Now scale the horizontal pen fraction by the point size
; specified in the grafPort. This is the same treatment that Color
; QuickDraw normally gives the chExtra value. Note that two values
; are added together before the scaling occurs.
; <18> 5/31/90 CL Fixing QDDone parameters so the goodÕol GC card works properly.
; <17> 5/30/90 JT For old grafPorts use the pnLocFixed value from the QuickDraw
; globals to created a fixed-point pen location. Added the
; penLocFixed local to record the value and restore it across
; recursive drawing operations on long strings.
; <16> 5/29/90 CL Fixed stretch bug in bitmap text.
; <15> 4/18/90 CL Needs32bit only is tested for a byte so set a byte instead of a
; word. The TrueType init does not contain the new bitstopix so we
; must set up the needs32bit flag up for the init. CrsrFlag broke
; the 68000 machines. It was included in the 68000 machines but
; never was initialized.
; <14> 4/16/90 HJR Correct some conditionals. Change SPLINE_FONTS to
; hasSplineFonts.
; <13> 4/16/90 KON File got trashed at rev 11, could be network weirdness or old
; ethertalk card.
; <12> 4/16/90 KON Make it build (equate problems).
; <11> 4/13/90 HJR Fix some case sensitive problem in Mac32 build.
; <10> 4/11/90 CL Added conditional for ROM to leave out is32QD flag since it is
; not needed and the splinekey since it does not exist.
; <9> 4/10/90 CL Fixing outline Text clipping bug. Conditionalize for ROM. Adding
; Double byte international coding.
; <8> 4/9/90 KON Fixed conditionals for ROM build. Script Manager char
; extra addition.
; <8> 4/9/90 KON Fixed problems with drawing to 32-bit addressed pixmaps that are
; not the screen. With BAL.
; <7> 3/21/90 CL Fixed conditionals for ROM build. Script Manager char extra
; addition.
; <6> 3/20/90 CL International character extra is added into QD char extra for
; $700 or greater systems. Non-rectangular visrgn clip did not
; work correctly. Bug in SE - did not scale up the glyphid in
; error case for the retrieval of the width char. Stack was not
; calculate correctly. Added positive value instead of negative.
; <5> 2/28/90 CL Can not do bit depth expansion when going to local off screen
; buffer. Fixes algorithmic boldening and other not fast cases
; <4> 2/27/90 CL Finishing previous comment. 2, 4 & 8-bit only uses 1bit source
; (saves tons of memory). 8 bit - Å120% faster. 2 and 4 - 110-120%
; faster. 16-bit - 200 to 300% faster. 32-bit - 400-500% faster. 1
; bit on Portable and SE - Å182% faster.
; <3> 2/27/90 CL Optimized clip spline blit loops (10% faster). Wrote new fast
; loops for splines in 1, 2, 4, 8, 16 and 32 bit depth levels.
; Optimized pathway setup. Timings for 12 pt. Text on the CI
; compared to 6.0.4 systems are as follows: 1 bit is - 200%
; faster
; <1> 1/3/90 BAL Added a notice for Chazz.
; <2.8> 11/28/89 CEL Characters can have zero widths. Took out check to skip
; character if it has a zero advance width. Especially caused
; problems for International.
; <2.7> 11/14/89 CEL Added Device left side bearing.
; <2.6> 10/27/89 BAL Only define hasSplineFonts if currently undefined. Also
; translate24to32 thePort.
; <2.5> 10/10/89 CEL Fixed the notsrccopy and mask transfer mode for bitmaps.
; <2.4> 9/25/89 CEL Took out left italic descent adjustment. This adjustment to the
; over hang could cause clipping of the string before it.
; <2.3> 9/15/89 CEL Took out tempAscent and tempDescent. Use the always blit flag
; instead. Added in some new blitting code that is not turned on
; yet. Cursor bug: when 32-bit QD was not around BitsToPix did not
; return d2 value for crsrflag.
; <2.2> 8/28/89 CEL Only used byte of spline flag.
; <2.1> 8/14/89 CEL Added support for temp memory for spline bitmaps. Now works
; better in finder mode. Added in ability to set line height for
; splines. Usage from the SetLineHeight function.
; <2.0> 8/1/89 CEL Somehow SUBQ turned into SUBA while checking inÉ
; <1.9> 8/1/89 CEL Only effects spline font builds: Re-organized spline define
; structures. Cleaned up stack and took out conditionals. Fixed
; mask mode for splines. Fixed kerning adjusting values. Added in
; more comments. Added banding to styles. Merged B&W code to take
; advantage of the Color QD iteration, Banding code in low memory
; and Multi-Finder memory usage. Now DrText works for over 10,000
; point for styles. Have tried 13,000 point in Shadow and works
; fine. Works at 32,767 point for plain. Used assembly record
; structures for easier mods. Added some code review changes.
; <1.8> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw private
; file (colorequ.a), got rid of QuickDraw nFiles dependencies and
; fixed up necessary filesÉ
; <¥1.7> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
; <¥1.6> 5/3/89 CEL Bass rolled into ROM. NOTE:Spline Fonts are conditionalized out.
; Blasting in correct file
; <¥1.4> 5/1/89 cel Rolled in BassÉ
; <¥1.2> 2/14/89 CCH Rolling in 32-Bit color quickdraw sources from Bruce Leak and
; Dave Fung.
; 9/19/88 BAL Altered to get CRSRFLAG value from _BitsToPix;
; 7/4/88 BAL Fixed offscreen drawing to compute bkcol with long result of
; color2index
; 5/8/88 BAL Altered to use 32 bit addressing mode and allow 32 bit deep
; pixels
; 1/21/88 BAL changed pnLocHFrac(a3) to PenLocHFrac(A6) so fractional position
; is restored
; 11/6/87 CRC changed to take fast branch case correctly (branch to GetPtrs,
; not NotScreen)
; 6/4/87 CRC reordered shadow draw to draw outline and then center in old
; port cases
; 1/12/87 CRC rewrote recursive part to avoid reallocating stack frame each
; time through
; 1/6/87 CRC only change the source pixmapÕs color table if the source is not
; 1 deep
; 1/3/87 CRC pass color param to stretch, estimate stack usage better, new
; outline/shadow allow initial left kerning, better right hand
; trim for outline
; 12/12/86 CRC Added support for arithmetic modes, character extra
; 12/8/86 CRC Faster case for characters contained in source longs
; 11/23/86 EHB Merged in multiple device changes
; 10/13/86 EHB Added MaskPix and MaskRect to stretchbits call
; 10/7/86 CRC Better measure of italic widths; italic character forces left
; kerning allow for larger strikes w/ long calcs.
; 9/29/86 CRC Changed WidthPtr to WidthTabHandle, added multibit font support
; 6/22/86 EHB Use BIC mode to clear out inner part of outline fonts. (XOR
; looked cool but was wrong).
; 6/18/86 EHB Added pattern to stretchbits calls
; 6/18/86 EHB Removed 68020 enhancements from charblt
; 6/17/86 EHB Added DSTPIX so we could access fields in cGrafPorts
; 6/15/86 EHB Make sure stack is longword aligned (for fast buffers)
; 6/10/86 EHB Modified to use longs and 68020 instructions
; 6/5/86 EHB Cleared flag bits in references to rowBytes
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
IF (&TYPE('hasSplineFonts') = 'UNDEFINED') THEN
hasSplineFonts EQU 0
ENDIF
IF (&TYPE('HAS_COLOR') = 'UNDEFINED') THEN
HAS_COLOR EQU hasCQD
ENDIF
IF (&TYPE('has32bitQD') = 'UNDEFINED') THEN
has32bitQD EQU 0 ;Once bits to pix is fixed we can turn this on and do
ENDIF ;some conditionals in compiling
IF (&TYPE('TIME_SPEED') = 'UNDEFINED') THEN
TIME_SPEED EQU 0
ENDIF
IF (&TYPE('INITVERSION') = 'UNDEFINED') THEN
Gaudi EQU 0
ELSE
Gaudi EQU 1
ENDIF
IF (&TYPE('hasDoubleByte') = 'UNDEFINED') THEN
IF forROM THEN
hasDoubleByte EQU 0
ELSE
hasDoubleByte EQU 1
ENDIF
ENDIF
IF (&TYPE('SCRIPT_CHAR_EXTRA') = 'UNDEFINED') THEN
IF forROM THEN
SCRIPT_CHAR_EXTRA EQU 0
ELSE
SCRIPT_CHAR_EXTRA EQU 1
ENDIF
ENDIF
IF (&TYPE('hasPenFraction') = 'UNDEFINED') THEN
IF forROM THEN
hasPenFraction EQU 0
ELSE
hasPenFraction EQU 1
ENDIF
ENDIF
IF (&TYPE('hasFullKerning') = 'UNDEFINED') THEN
IF forROM THEN
hasFullKerning EQU 0
ELSE
hasFullKerning EQU 1
ENDIF
ENDIF
MACHINE MC68020 ;<PN>
IF (NOT forROM) THEN ; <31> DTY <PN> <SM3> CSS
CASE OBJ
ENDIF
IF (NOT forROM) THEN ;<1.6-11april89-CEL> & <31> DTY
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Include filesÉ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
INCLUDE 'sysequ.a' ;for SplineKey low mem
INCLUDE 'Traps.a'
INCLUDE 'Quickequ.a'
INCLUDE 'ColorEqu.a'
INCLUDE 'ToolEqu.a'
INCLUDE 'QDHooks.a'
INCLUDE 'SplineDefines.a'
INCLUDE 'fontPrivate.a'
INCLUDE 'SysPrivateEqu.a'
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
ENDIF ;<1.6-11april89-CEL>
INCLUDE 'LinkedPatchMacros.a' ; <31> DTY
INCLUDE 'InternalOnlyEqu.a' ; <PN>
if (hasDoubleByte) then
include 'Script.a'
endif
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;
; PROCEDURE DrText(count: INTEGER; textAddr: Ptr; numer,denom: Point);
;
; DRAWS CHARACTERS INTO THE CURRENT PORT'S BITMAP.
; THE FONT AND ATTRIBUTES ARE GIVEN IN THE CURRENT PORT'S CHARSTYLE.
;
; DrText will handle both bitmap ÔFONTÕs, ÔNFNTÕs and new spline font
; ÔsfntÕs.
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
DrText PROC EXPORT
; If the portVersion/rowBytes of any port has the following bits set, it is a GWorld
GWorldFlag equ $C001 ; isPixMap+isCPort+isGWorld
IF TIME_SPEED THEN
IMPORT INITTIMER, READTIMER, RESETTIMER
ENDIF
IMPORT ArithMode
IMPORT GetStyleBufHand
IMPORT CalcCharExtra
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Font structure for bitmaps
;
; KERNED STRIKE FONT FORMAT OFFSETS:
;
FORMAT EQU 0 ;WORD
MINCHAR EQU 2 ;WORD
MAXCHAR EQU 4 ;WORD
MAXWD EQU 6 ;WORD
FBBOX EQU 8 ;WORD fKernMax
FBBOY EQU 10 ;WORD save as nDescent; unused except as high owTLoc
FBBDX EQU 12 ;WORD fRectWidth
FBBDY EQU 14 ;WORD fRectHeight
LENGTH EQU 16 ;WORD owTLoc
locASCENT EQU 18 ;WORD Conflict with other Ascent and Descent defines
locDESCENT EQU 20 ;WORD
XOFFSET EQU 22 ;WORD leading
RASTER EQU 24 ;WORD rowWords
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Input parameters
;
; A6 OFFSETS OF PARAMETERS AFTER LINK:
;
PARAMSIZE EQU 14 ;SIZE OF PARAMETERS
COUNT EQU PARAMSIZE+8-2 ;WORD
TEXTADDR EQU COUNT-4 ;LONG
NUMER EQU TEXTADDR-4 ;LONG, POINT
DENOM EQU NUMER-4 ;LONG, POINT
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Stack Frame for locals
;
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
;
SAVESTK EQU -4 ;long stack before allocating buffers
TEXTRECT EQU SAVESTK-8 ;RECT original bounding rect
TEXTR2 EQU TEXTRECT-8 ;RECT copy of textRext used by maprect
SRCRECT EQU TEXTR2-8 ;RECT original shadow bounding rect
DSTRECT EQU SRCRECT-8 ;RECT copy of srcRect used by maprect
MINRECT EQU DSTRECT-8 ;RECT minimum rect for clipping
BUFEND EQU MINRECT-4 ;LONG where the offscreen buffer ends
BUFSIZE EQU BUFEND-4 ;LONG the size of the offscreen buffer
BUFROW EQU BUFSIZE-2 ;WORD the rowBytes for the offscreen buffer
BUF2START EQU BUFROW-4 ;LONG second buffer used for shadow
BUF2END EQU BUF2START-4 ;LONG where shadow buffer ends
BUFLEFT EQU BUF2END-2 ;WORD output left edge
sHeight EQU BUFLEFT-2 ;WORD font fRectHeight copy
SRCPTR EQU sHeight-4 ;LONG used only in wide character case as temp
DSTPTR EQU SRCPTR-4 ;LONG used only in wide character case as temp
maskStart EQU DSTPTR-4 ;LONG \ start of mask buffer
maskAddr EQU maskStart-4 ;LONG >- these 3 grouped: address of mask bits
mSrcRow EQU maskAddr-4 ;LONG / rowbytes of mask bits
FROMRECT EQU mSrcRow-8 ;RECT mapRect parameter
TORECT EQU FROMRECT-8 ;RECT mapRect parameter
PENLOC EQU TORECT-4 ;POINT copy of original pnLoc
SPWIDTH EQU PENLOC-4 ;FIXED POINT width of space
CHARLOC EQU SPWIDTH-4 ;FIXED POINT fractional pen position
HEIGHTAB EQU CHARLOC-4 ;LONG pointer to font height table
WIDTAB EQU HEIGHTAB-4 ;LONG pointer to font offset/width table
LOCTAB EQU WIDTAB-4 ;LONG pointer to font location table
SAVEA5 EQU LOCTAB-4 ;LONG register saved so can be reused
characterExtra EQU SAVEA5-4 ;LONG fixed point extra added to each character
maskBitsPtr EQU characterExtra-4 ;LONG pointer to maskBits, sourcePix, or 0
bkCol EQU maskBitsPtr-4 ;LONG full of the background color
leftBack EQU bkCol-4 ;LONG bkCol masked to the left part of the character
rightBack EQU leftBack-4 ;LONG bkCol masked to the right part of the character
realBounds EQU rightBack-4 ;LONG USED FOR SHIELDCURSOR
leftOffset EQU realBounds-8 ;2 LONGs offset used by bit field instructions in charblt
maskSize EQU leftOffset-2 ;WORD size of mask buffer
mBufRow EQU maskSize-2 ;WORD \ these 2 mask buffer row size
maskBlts EQU mBufRow-6 ;3 WORDS / grouped: saved state for mask blit
FAKERGN EQU maskBlts-10 ;RECTANGULAR REGION
FAKEPTR EQU FAKERGN-4 ;LONG, FAKE MASTER POINTER
INFO EQU FAKEPTR-8 ;4 WORDS font info record returned by txMeasure (unused)
numer2 EQU INFO-4 ;Point copy of numer for iterative case
denom2 EQU numer2-4 ;Point copy of denom for iterative case
charsRemain EQU denom2-2 ;word remaining characters to draw in iterative case
srcBits EQU charsRemain-14 ;bitMap input to shadow stretchBits, bitsToPix
srcPix EQU srcBits-(pmRec+ctRec+20) ;pixMap input to normal stretchbits
maskBits EQU srcPix-14 ;bitMap input to bitsToPix for font mask
DSTPIX EQU maskBits-(pmRec+ctRec+20) ;pixMap destination
FASTFLAG EQU DSTPIX-1 ;BYTE flag set if source ORing to screen is OK
maskFont EQU FASTFLAG-1 ;byte flag set if a maskFont is available + requested
Stretch EQU maskFont-1 ;BOOLEAN flag set if numerator not equal denominator
heightFlag EQU Stretch-1 ;byte flag set if font has a height table
topHt EQU heightFlag-2 ;word character top & height from font or clip
maxMin EQU topHt-2 ;word number of characters in font
minCh EQU maxMin-2 ;word first character in font
bitDepth EQU minCh-2 ;word \ These two bits per pixel in font
bkCol1 EQU bitDepth-2 ;word / grouped. 1 pixel worth of background color
kernAdjust EQU bkCol1-2 ;word pen adjustment to kerning and italic
kernBounds EQU kernAdjust-2 ;word boundary adjustment due to kerning and italic
penLocHFrac EQU kernBounds-2 ;word fractional pen position for recursive calls
penLocFixed EQU penLocHFrac-2 ;word fractional pen position for recursive calls
longCount EQU penLocFixed-2 ;word loop counter for doMove
charWidth EQU longCount-2 ;word width in pixels of current character blt
stackOffset EQU charWidth-2 ;word 2 if stack was word aligned before link
countCopy EQU stackOffset-2 ;word copy of character count, decremented as drawn
CRSRFLAG EQU countCopy-1 ;BYTE set if crsr is shielded (to screen) <1.6-11april89-CEL>
MMUSave EQU CRSRFLAG-1 ;BYTE MMU mode on entry to drawText <1.6-11april89-CEL>
locMode EQU MMUSave-2 ;word copy of text mode, adjusted if arith. + 1 bit <1.6-11april89-CEL>
bitShift EQU locMode-2 ;word how far to shift to multiply by bitDepth
orNotOK EQU bitShift-1 ;Boolean true if bit extract/insert must be used instead
notMaskPass EQU orNotOK-1 ;Boolean true if blit is not creating font mask
textCopyMode EQU notMaskPass-1 ;Boolean true if blit must use extract/insert
orMode EQU textCopyMode-1 ;Boolean true if mode is srcOr & forecolor is black
colorSource EQU orMode-1 ;Boolean true if font contains colors (nonblack/white)
saveHilite EQU colorSource-1 ;byte saved hilite flag for iterative state
unused1 EQU saveHilite-1 ;byte extra byte for somebody maybe Snapper-Head Joe
is32QD EQU unused1-1 ;32 bit QD is around
sAscent EQU is32QD-2 ;word for Ascent
sDescent EQU sAscent-2 ;word for Descent
rExtraHang EQU sDescent-2 ;word Right over hang max
repeatBands EQU rExtraHang-2 ;word repeat banding for clipping regions off stack
LItalicExtra EQU repeatBands-2 ;word Left italic extra
RItalicExtra EQU LItalicExtra-2 ;word Right italic extra
isSpline EQU RItalicExtra-1 ;byte for flag
cacheState EQU isSpline-1 ;byte memory state for cache
fontState EQU cacheState-2 ;word Save the state of the font
clipStorage EQU fontState-4 ;long pointer to top of stack for clipping
origCharCount EQU clipStorage-2 ;long pointer to top of stack for clipping
saveMode EQU origCharCount-2 ;Transfer mode safe copy
origTopClip EQU saveMode-2 ;WORD yMax Clipping
origBotClip EQU origTopClip-2 ;WORD yMin Clipping
bufHeight EQU origBotClip-2 ;Height of buffer needed
currentEnd EQU bufHeight-4 ;Current end of style buffer for allocation
bufferPtr EQU currentEnd-4 ;Pointer to style buffer
stackHandle EQU bufferPtr-4 ;Handle to style buffer
trimSrcRect EQU stackHandle-8 ;RECT trimmed source rect for init
cacheHand EQU trimSrcRect-4 ;Handle to the cache
cachePtr EQU cacheHand-4 ;Pointer to the cache
glyphArray EQU cachePtr-4 ;Pointer to the glyph array
topAdjust EQU glyphArray-2 ;(word)Top adjustment to calc destination
widTabPtr EQU topAdjust-4 ;(long)Pointer to the fixed width table
STARTTIME EQU widTabPtr-4 ;reserved for Chazz-man TIMINGS
READADJ EQU STARTTIME-4 ;reserved for Chazz-man TIMINGS
wordFunc EQU READADJ-4 ;pointer to word blit routine
bigWordFunc EQU wordFunc-4 ;pointer to big word blit routine
longFunc EQU bigWordFunc-4 ;pointer to long blit routine
bigLongFunc EQU longFunc-4 ;pointer to big long blit routine
overLongFunc EQU bigLongFunc-4 ;pointer to over long blit routine
destShift EQU overLongFunc-2 ;word destination shift value
textPtr EQU destShift-4 ;copy of text addr
a4Check EQU textPtr-4 ;Temporary may rip out later - only checking for stack crash
a6Check EQU a4Check-4 ;Temporary may rip out later - only checking for stack crash
needs32Bit EQU a6Check-1 ;used by KON-mon, device deeds to be addressed in 32-bit mode
notFastFlag EQU needs32Bit-1 ;do not go fast if set
rOverHMax EQU notFastFlag-2 ;word right overhang maximum
lowByte EQU rOverHMax-1 ;(boolean) is this a double-byte font?
highByte EQU lowByte-1 ;(byte) low-byte of double-byte character.
encodingTable EQU highByte-4 ;(pointer) encoding table address.
FREEBYTE EQU encodingTable-1 ;(byte)
doDither EQU FREEBYTE-1 ;(byte) Set if dither is needed
synFont EQU doDither-1 ;(byte) Set if this is a synthetic font
fluff EQU synFont-1 ;(byte)
myPort EQU fluff-4 ;The current grafport
maskTabPtr EQU myPort-4 ;ptr to mask table <62-CEL>
resvLong1 EQU maskTabPtr-4 ;reserved for Chazz-man <62-CEL>
resvLong2 EQU resvLong1-4 ;reserved for Bruce-dude
resvLong3 EQU resvLong2-4 ;reserved for Kon-chap
resvLong4 EQU resvLong3-4 ;reserved for Kindness
resvLong5 EQU resvLong4-4 ;reserved for Joe-schmoe
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;sb_Retrieves input struct - Do not split this record up!!!
;###WARNING: If this changes, then change the same record in OutlineMetrics.a
bufStart EQU resvLong5-4 ;(long) _ \ start of bits buffer <jdt 14Mar90>
srcAddr EQU bufStart-4 ;(long) | >- these 3 grouped: ptr to bits
srcRow EQU srcAddr-4 ;(long) |/ rowbytes of font bits
bitWidth EQU srcRow-2 ;(word) | for Width of char in bits
entryOffset EQU bitWidth-4 ;(long) | entry offset of glyph
fillBYTE EQU entryOffset-1 ;(Boolean) |
nextBand EQU fillBYTE-1 ;(Boolean) | Another character band?
nextTopBand EQU nextBand-2 ;(word) | next top character band
nextBotBand EQU nextTopBand-2 ;(word) | next bot character band
bandScan EQU nextBotBand-2 ;(word) | band size of char band
scan EQU bandScan-2 ;(word) | number of scan lines
devLSB EQU scan-2 ;(short) | Device for the LSB (short)
lsb EQU devLSB-4 ;(long) | for the LSB (fixed)
yMax EQU lsb-2 ;(word) | for the y min (short)
yMin EQU yMax-2 ;(word) | for the y max (short)
topClip EQU yMin-2 ;(word) | yMax Clipping
botClip EQU topClip-2 ;(word) | yMin Clipping
clipHorz EQU botClip-1 ;(Boolean) \ | Is it clipped horizontally
clipVert EQU clipHorz-1 ;(Boolean) / | Is it clipped vertically
destDepth EQU clipVert-2 ;(word) | depth of destination **CAN take out
ptSize EQU destDepth-2 ;(word) | pixels per em **CAN take out
glyphID EQU ptSize-2 ;(word) | glyph code
fontID EQU glyphID-2 ;(word) _ font id code *** get rid of unwanted vars
;End of Structure
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
VARSIZE EQU ((fontID-3)/4)*4 ;SIZE OF VARIABLES long aligned <6> CEL
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Aligning the Stack
;
; MAKE SURE THE STACK IS ON A LONGWORD BOUNDARY (FOR FASTBUFFERS)
;
; Register Use:
; A3 = thePort
; A4 = QuickDraw Globals
; A6 = Stack frame
; A5 = Grafport handle
;
; Clobbers:
; D0
;
MOVE.L D0,A0 ;save D0 $$$ WHY
MOVE.L SP,D0 ;GET THE STACK POINTER
ASR #2,D0 ;WORD BOUNDARY?
SCS D0 ;remember balance
BCC.S STKOK ;=>NO, GOT LONG BOUNDARY
SUBQ #2,SP ;ELSE MAKE STACK LONG ALIGNED
STKOK
LINK A6,#VARSIZE ;ALLOCATE TEMP VARS
AND #2,D0 ;amount stack was adjusted by
MOVE D0,stackOffset(A6)
MOVE.L A0,D0 ;restore D0 $$$ WHY
MOVEM.L D0-D7/A1-A4,-(SP) ;SAVE REGS
MOVE.L SP,SAVESTK(A6) ;remember where the stack was
MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A4),A3 ;GET CURRENT GRAFPORT
IF (hasSplineFonts OR Gaudi) THEN
MOVE.L expandMem,A0 ; get low memory expand pointer. <61-CEL/RWB>
MOVE.L ExpandMemRec.emSplineKey(A0),A0 ; get handle to splineKey globals. <61-CEL/RWB>
MOVE.L (A0), A0 ; get pointer to splineKey globals. <61-CEL/RWB>
MOVE.W #-2, splineKeyRec.safeCount(A0) ;init to -1 for flagging <61-CEL/RWB>
ENDIF
MOVE.B splineKeyRec.is32bit(A0),is32QD(A6) ; get 32 bit CQD flag in CCR.
MOVE.L TheGDevice,LastTxGDevice ;save the text device for next time
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;
; CONVERT DSTBITS (THE PORT) TO A PIXMAP
; (A5 must contain global ptr)
;
LEA PORTBITS(A3),A1 ;GET PORTBITS POINTER
LEA DSTPIX(A6),A2 ;GET DSTPIX POINTER
_BitsToPix ;CONVERT BITMAP
MOVE.L D1,REALBOUNDS(A6) ;SAVE REAL DST BOUNDS.TOPLEFT
IF NOT Gaudi THEN
MOVE.B D2,CRSRFLAG(A6) ;REMEMBER IF DST IS SCREEN <BAL 18Sep88>
swap d2 ; <9Apr90 KON>
move.b d2,needs32Bit(a6) ;save whether device needs 32-bit addressing<7Apr90 KON>
ELSE
CLR.B needs32Bit(a6) ;Set if 32-bit
TST.B is32QD(A6) ;check for 32 bit QD
BEQ.S @no32QD ;no so do it the old way
MOVE.B D2,CRSRFLAG(A6) ;REMEMBER IF DST IS SCREEN <BAL 18Sep88>
BNE.S @checkScreen ;yes -> check gdevice
LEA DSTPIX(A6),A2 ;GET DSTPIX POINTER
MOVE.W pmVersion(A2), D0 ;if flags are set check if 32-bit addressing
BEQ.S @doneSetFlag ;not needing 32 bit addressing so branch
BTST #2,D0 ;32-bit clean address?
SNE needs32Bit(A6) ;Set if 32-bit
BRA.S @doneSetFlag
@checkScreen
MOVE.L THEGDEVICE,A0 ;GET HANDLE TO THE GDEVICE
MOVE.L (A0),A0 ;GET POINTER TO THE GDEVICE
BTST #ext32Device,gdFlags(A0) ;does it need 32-bit addressing?
SNE needs32Bit(a6) ;Set if 32-bit
BRA.S @doneSetFlag
@no32QD
MOVE.L TheGDevice, A0 ;Get the gdevice
MOVE.L (A0), A0 ;Point at it
MOVE.L GDPMAP(A0), A0 ;Get its pixmap
MOVE.L (A0),A0 ;Point at it
MOVE.L BASEADDR(A0),D0 ;Get base of screen
CMP.L DSTPIX+BASEADDR(A6),D0 ;Drawing to the screen
SEQ CRSRFLAG(A6) ;If so, set it
@doneSetFlag
ENDIF ;Gaudi
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Load the matching Font and Measure the string
;
;
MOVE stackOffset(A6),D0 ;either zero if stack was long aligned, or two if not
CLR -(SP) ;ROOM FOR FCN RESULT
MOVE.L numer(A6,D0),numer2(A6)
MOVE.L denom(A6,D0),denom2(A6) ;save original numer, denom for iterative case
MOVE COUNT(A6,D0),D1 ;get count
MOVE D1,-(SP) ;PUSH COUNT
MOVE D1,countCopy(A6) ;save copy of count
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
MOVE D1,origCharCount(A6) ;save copy of count
ENDIF
MOVE.L TEXTADDR(A6,D0), A0
MOVE.L A0, textPtr(A6) ;Keep a copy for later use
MOVE.L A0, -(SP) ;PUSH TEXTADDR
PEA NUMER(A6,D0) ;PUSH VAR NUMER
PEA DENOM(A6,D0) ;PUSH VAR DENOM
PEA INFO(A6) ;PUSH VAR INFO
lea JStdTxMeas,A0 ;get piece of trap table <31> DTY Changed from move.l
move.l (a0),a0
JSR (A0) ;MEASURE TEXT
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Set up mask table ptr
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Fix for overflow of stdtxmeas
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
IF (hasSplineFonts OR Gaudi) THEN ; <31> DTY <59-CEL/RWB>
MOVE.L expandMem,A0 ; get low memory expand pointer. <59-CEL/RWB>
MOVE.L ExpandMemRec.emSplineKey(A0),A0 ; get handle to splineKey globals. <59-CEL/RWB>
MOVE.L (A0), A0 ; get pointer to splineKey globals. <59-CEL/RWB>
CMP.B #-1, splineKeyRec.safeCount(A0) ; check to see if count changed <59-CEL/RWB>
BEQ.S @noOverFlow ; <59-CEL/RWB>
MOVE.W splineKeyRec.safeCount(A0), D1 ;get safe count in reg for assigns <59-CEL/RWB>
MOVE stackOffset(A6),D0 ;either zero if stack was long aligned, or two if not <59-CEL/RWB>
MOVE D1, COUNT(A6,D0) ;new count <59-CEL/RWB>
MOVE D1, countCopy(A6) ;save copy of count <59-CEL/RWB>
MOVE D1, origCharCount(A6) ;save copy of count <59-CEL/RWB>
@noOverFlow ; <59-CEL/RWB>
ENDIF
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Get the Width in D1
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
ADDQ #2,SP ;POP (and ignore) UNSCALED WIDTH RESULT
MOVE.L fontAdj(A4),D1 ;get fixed point width
MOVE.L fontPtr(A4),A4 ;Point to FmOutput record
move portVersion(a3),d0 ; get the port's portVersion/rowBytes
and #GWorldFlag,d0 ; mask all other bits than the GWorldFlag
cmp #GWorldFlag,d0 ; is it exactly equal to GWorldFlag?
BNE.S @1
MOVEM.L A0-A1/D0-D2,-(SP) ;Save registers
clr.l -(sp) ; leave room for Ptr result
move.l portPixMap(a3),-(sp) ; push handle to pixmap
_GetPixBaseAddr ; get address of offscreen buffer
move.l (sp)+,d0 ; put it in d0
MOVE.L D0, DSTPIX+BASEADDR(A6) ;
MOVEM.L (SP)+, A0-A1/D0-D2 ;Restore registers
ST needs32Bit(A6) ; sending 32-bit data
@1 MOVE.W dstPix+pixelSize(A6),destDepth(A6) ;Get the pixel depth
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; DO FORK
;
; Check if splines or bitmaps and make the fork!!!
;
;
if (hasDoubleByte) then
clr.l encodingTable(a6) ; assume no encoding table.
endif
MOVE.L WidthTabHandle, A1 ;Get the Width Table
MOVE.L (A1), A1 ;Dereference the table
TST.B WidthIsSpline(A1) ;Is it a spline font
BEQ BitVarSetUp ;Not spline then branch
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; STARTING hasSplineFonts SETUP
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; SPLINE Stack Variable SetUp
;
; Registers on Entry:
; A4 = Graf globals
;
; Registers used:
; A1 = WidthPtr
; A6 = Stack frame
; A4 = FmOutput record ptr
;
; Preserves:
; D1 = Width of string (We could save it on the stack to be safe!!!
;
; CLOBBERS: D0, D2, D3
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Set flags
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
ST isSpline(A6) ;Set is a spline font
SF clipVert(A6) ;Init to no clip <6> CEL
SF doDither(A6) ;No dither for 1-bit splines
SF clipHorz(A6) ;Init to no clip <6> CEL
SF nextBand(A6) ;init to no next char band
CLR.L maskBitsPtr(A6) ;assume no mask
CLR.L stackHandle(A6) ;clear stackHandle
CLR.W repeatBands(A6) ;no banding at first
CLR.W bitShift(A6) ;Incoming 1 deep
CLR.W kernAdjust(A6) ;init kern value
CLR.W rExtraHang(A6) ;init rExtraHang value
CLR.B stretch(A6) ;set up bit insert/extract flag
CLR.B colorSource(A6) ;if so, pass info to stretch later
MOVE.W #1,bitDepth(A6) ;bits per pixel
MOVE.B WidthNotFast(A1), notFastFlag(A6) ;Looks like fast if set
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; get cache and Save metrics on stack
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
WITH cache ; <47-CEL>
MOVE.L expandMem, A2 ; get low mem expand <47-CEL>
MOVE.L ExpandMemRec.emSplineKey(A2), A2 ; Handle to splineKey <47-CEL>
MOVE.L (A2), A2 ; pointer to splinekey <47-CEL>
MOVE.L splineKeyRec.cacheHand(A2), D2 ; Do we even have a cache???
BEQ GOHOME ; bail since we have no cache
MOVE.L D2, A2 ;cacheHand in Addr reg
MOVE.L A2, cacheHand(A6) ;get a copy of cache hand
MOVE.L (A2), D2 ;cache pointer
BEQ GOHOME ;is purged? <65-CEL>
MOVE.L D2, A2 ;pointer to the cache in addr reg
if (hasDoubleByte) then
move.l fEncodingTablePointer(a2),encodingTable(a6) ; load encoding table pointer.
endif
MOVE.W yMax(A2), sAscent(A6) ;set stack Ascent
MOVE.W yMin(A2), sDescent(A6) ;Place descent on stack
MOVE.W height(A2), sHeight(A6) ;Place Height on stack
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; OverHang calcs
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;regs used:
; D2 = cachePtr
; A2 = glyphArrayPtr
;
MOVEQ #0,D5
MOVEQ #0,D3
if (hasDoubleByte) then
tst.l encodingTable(a6) ; <SM4> CSS <76> Is this a double byte font?
bz.s @getFirstAndLastCharacters ; <SM4> CSS <76> If not, donÕt add these overhang values
move.w rOverHMax(a2),d0 ; get right overhang value
add.w rightItalic(a2),d0 ; add in possible italic overhang
move.w d0,rExtraHang(a6) ; initialize total right overhang
endif
ENDWITH
@getFirstAndLastCharacters
MOVE.L textPtr(A6),A0 ;pointer to the text
MOVE countCopy(A6),D0 ;get count <6> CEL use d0 instead of d3
SUBQ.W #1, D0 ;count-1 is last char index
MOVE.B (A0),D5 ;first character
MOVE.B (A0,D0),D3 ;last character <6> CEL
if (hasDoubleByte) then
move.b d5,highByte(a6) ; save the high byte for later use.
clr.b lowByte(a6) ; clear the low byte for now
tst.l encodingTable(a6) ; is this a double byte font?
beq.s @normalFont ; no, skip low byte loading
move.l encodingTable(a6),a2 ; load the encoding table
tst.b 0(a2,d5.w) ; is this a double byte character?
beq.s @normalCharacter ; no, skip low byte loading
move.w countCopy(a6),d0 ; get the text length
cmpi.w #1,d0 ; is there a low byte character?
bls @remapCharacterToNull ; no, remap the high byte
adda.w #256,a2 ; offset to the lowByte encoding table.
clr.w d0 ; clear high byte of low word
move.b 1(a0),d0 ; grab the low byte.
tst.b 0(a2,d0.w) ; is this a valid low byte?
beq @remapCharacterToNull ; no, remap the high byte
move.b d0,lowByte(a6) ; save the valid low byte for later use
bra @normalCharacter ; continue normally.
@remapCharacterToNull
move.b #1,d5 ; remap the high byte character
move.b d5,highByte(a6) ; save the remapped value in the stack for later use
bra @doRSB ; skip the rest of this stuff
@normalCharacter
@normalFont
endif
MOVE.L D2, A0 ;cache pointer
LEA cache.glyphArray(A0), A2 ;Get array of glyphs into A2
MOVE.L 0(A2,D5*4),D0 ;Get offset to glyph in D0
BGT.S @okayGlyph
BTST.L #30, D0 ;Check if there is an error
BNE.S @doRSB ;branch if error
AND.L #$3FFFFFFF, D0 ;Clear contour entry bit flag
BNE.S @okayGlyph ;Got the info
BSR renderChar ;get the glyph and returns non-zero error
BEQ.S @doRSB ;skip this glyph <58-CEL>
BRA.S @checkLSB ;did not get the offset <58-CEL>
@okayGlyph
ADD.L D2, D0 ;glyphrec = cache + offset
MOVE.L D0, A0 ;in address reg
if (hasDoubleByte) then
clr.l d0 ; clear a long for the character code
move.b lowByte(a6),d0 ; double byte character?
beq.s @checkLSB ; no, skip this
move.l 0(a0,d0.w*4),d0 ; load glyph record offset
bgt.s @haveGlyphOffset ; skip checks if positive
btst.l #30,d0 ; error rendering glyph?
bne.s @doRSB ; yes, skip this glyph
and.l #$3fffffff,d0 ; clear contour and error flags
bne.s @haveGlyphOffset ; skip rendering if positive
bsr renderChar ; can render the glyph?
beq.s @doRSB ; no, skip this glyph
bra.s @checkLSB ; already have the offset
@haveGlyphOffset
add.l d2,d0 ; convert offset to pointer
move.l d0,a0 ; load glyph record pointer
endif
@checkLSB
MOVE.W glyph.devLSB(A0), D0 ;Get integralized left side bearing
BGE.S @doRSB
ADD.W D0, kernAdjust(A6) ;Save extra copy that can contain italic extra
@doRSB
if (hasDoubleByte) then
tst.l encodingTable(a6) ; is this a double byte font?
bne.s @doneOverHang ; yes, skip overhang calculations
endif
MOVE.W D3, D5 ;copy of D3
MOVE.L 0(A2,D3*4),D0 ;Get offset to glyph in D0
BGT.S @okayGlyph2
BTST.L #30, D0 ;Check if there is an error
BNE.S @doneOverHang
AND.L #$3FFFFFFF, D0 ;Clear contour entry bit flag
BNE.S @okayGlyph2 ;Got the info
MOVE.W D5, D0 ;D0 for renderchar
BSR renderChar ;get the glyph and returns non-zero error
BEQ.S @doneOverHang ;skip this glyph <58-CEL>
BRA.S @calcROverHang ;got the glyph <58-CEL>
@okayGlyph2
ADD.L D2, D0 ;add offset and point to glyph data
MOVE.L D0, A0 ;Get in address reg
@calcROverHang
MOVE.W 0(A1,D3*4),D0 ;Get the width
MOVE.W glyph.devLSB(A0), D3 ;Get integralized left side bearing
ADD.W glyph.bitWidth(A0), D3 ;RoverHang = (lsb+bitwidth)-Width
SUB.W D0, D3 ;
BLE.S @doneOverHang
MOVE.W D3, rExtraHang(A6)
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; End OverHang calcs
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
@doneOverHang
MOVE.W sAscent(A6), topClip(A6) ;Assign Ascent as top clip initially
MOVE.W sDescent(A6), botClip(A6) ;opened up bot clip
MOVE.W botClip(A6), origBotClip(A6);Init for fakergn check
MOVE.W topClip(A6), origTopClip(A6);Init for fakergn check
MOVE txMode(A3),D0
AND #$FFF7,D0 ;clear pattern bit (let stretch reject invalid modes)
MOVE D0,locMode(A6) ;initialize copy
BTST #6,D0 ;bit 6 if set says use a mask
SNE D3 ;remember it
BEQ.S @notMask
LEA srcPix(A6),A0 ;assume no mask font needed; just use source instead
MOVE.L A0,maskBitsPtr(A6) ;pass mask to stretch bits
@notMask
MOVE.B D3,maskFont(A6) ;0 if mask bit clear, no mask font, or incoming 1 deep
MOVE.B D3,textCopyMode(A6) ;set up bit insert/extract flag
BTST #5,D0 ;arithmetic mode?
BEQ.S @doneMode ;if not, donÕt map if dest. is 1 bit deep
CMP #1,dstPix+pixelSize(A6) ;1 bit deep destination?
BNE.S @doneMode ;if not, arithmetic mode is OK
LEA ArithMode,A0 ;get mode map
AND #7,D0 ;look at each different arith mode
MOVE.B 0(A0,D0),D0 ;map into 1 bit safe mode
MOVE D0,locMode(A6) ;alter mode properly for 1 bit depth
@doneMode
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Bounding Rect set up
;
; Setup textRect, the rectangle bounding the entire string.
;
; Registers on Entry:
; A2 = Font Ptr
; A3 = thePort
; A4 = FmOutput record ptr
; A6 = Stack frame
;
; D1 = Width of string
;
; Register Use:
; D2 = PenLocation (Set up as fixed)
;
; Clobbers:
; D0, D3
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L PNLOC(A3),D2 ;GET PEN LOCATION
MOVE.L D2,PENLOC(A6) ;SAVE FOR LATER
MOVE.W D2,TEXTRECT+LEFT(A6) ;TEXTRECT.LEFT := PNLOC.H
SWAP D2
IF hasPenFraction THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals.
move.w pnLocFixed(a0),d2 ; append pen fraction.
move.w d2,penLocFixed(a6) ; save pen fraction for recursive drawing.
ELSE
move.w #$8000,d2 ; append default fraction.
ENDIF
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; set flag to note if mode is srcOr & foreColor is black
; set up characterExtra if new port or script manager around
; set up pnLocHFrac if new port
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
CMP #srcOr,locMode(A6) ;is the mode srcOr?
SEQ orMode(A6)
BCLR #6,locMode+1(A6) ;was mask set?
BEQ.S @noMaskMode
TST locMode(A6) ;is it srcCopy + mask?
SEQ orMode(A6) ;that can go fast, too.
@noMaskMode
moveq #0, d0 ; clear the character extra. <49>
tst.b portBits+rowBytes(a3) ; is this an old grafPort?
bpl.s @oldGrafPort ; yes -> skip this.
move.w chExtra(a3),d0 ; load the character extra.
ext.l d0 ; for sign bits <49>
asl.l #4,d0 ; convert to 16.16 format.
@oldGrafPort
IF SCRIPT_CHAR_EXTRA THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals. <43>
add.l qdChExtra(a0),d0 ; add in the character extra. <43>
ENDIF
tst.l d0 ; have zero character extra?
beq.s @zeroCharExtra ; yes -> skip call to scale.
bsr CalcCharExtra ; scale by point size, etc.
@zeroCharExtra
move.l d0,characterExtra(a6) ; store scaled character extra.
TST PORTBITS+ROWBYTES(A3) ; is it a new port?
BPL.S @useOld1 ; no -> donÕt set up fraction
MOVE pnLocHFrac(A3),D2 ; set up with proper fraction
MOVE D2,penLocHFrac(A6) ; save for later as well for recursive drawing
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; ForeGround - BackGround check
;
; This next part is a little tricky:
; If the source does not contain any colors (that is, regardless of whether the source is
; one bit per pixel or more, the pixels are either black or white) then we can go fast if
; the forecolor is black, regardless of the background color. If the font does contain colors,
; then we can go fast if the background is white, regardless of the foreground colors.
;
; But, if the foreground and background pixels are equal (but the font is a 1 bit font), then go
; slow. ColorMap will be called later to sort out whether the foreground color needs to be
; remapped or not.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; This is the real code
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L fgColor(A3),D0
MOVE dstPix+pixelSize(A6),D3 ;bits per pixel
CMP.W #1, D3 ;1 bit depth???
BNE.S @multiDepth
CMP.L bkColor(A3),D0 ;same as background? <66>
beq.s @goSlow ; <66>
tst.l d0 ;forecolor white? <66>
BNE.S @doneCheck ;We are okay
BRA.S @goSlow ;forecolor white, use stretch <66>
@multiDepth
CMP.W #16, D3 ;16 or 32 bit???
BLT.S @not16or32
TST.L D0 ;If zero then black
BEQ.S @doneCheck ;Do not change mode if black
CLR.B orMode(A6) ;Do not do fast case
BRA.S @doneCheck ;done so continue
@not16or32
CMP.L bkColor(A3),D0 ;same as background?
BEQ.S @goSlow ;if so, go slow
ADDQ.L #1,D0 ;now equal to number of colors, if black
LSR.L D3,D0 ;1 if black, 0 if other color
@goSlow
SNE D0 ;remember if black (or if fg/bk pixels are not equal)
BRA.S @oldCommon
@useOld1
BTST #5,fgColor+3(A3) ;is the foreground color black?
SNE D0 ;set to zero if not
@oldCommon
AND.B D0,orMode(A6) ;true if or mode and black monochrome or white multi.
@doneCheck
ADD.L D1,D2 ;right := left + width
SWAP D2 ;just look at high word
TST.B fmOutCurStyle(A4)
BEQ @noSlop ;if no style, certainly no slop
MOVEQ #0,D0 ;clear out high word
ADD.B fmOutBold(A4),D0 ;add boldness
EXT D0 ;make it a word
MOVEQ #4,D3 ;restrict shadow in the range of 0 .. 3 (+1 if shadow)
CMP.B fmOutShadow(A4),D3 ;is it less or same?
BLE.S @pinShadow ;if so, pin at limit
MOVE.B fmOutShadow(A4),D3 ;otherwise, pass actual value
BEQ.S @pinShadow
ADDQ #1,D3 ;plus 1 for character insides shifted to right
@pinShadow
ADD D3,D0 ;combine shadow with italic slop count
ADD D0,D2 ;SLOP FOR ITALIC,BOLD,OVERSTRIKE
@noSlop
MOVE.W kernAdjust(A6), D0 ;reg for add
ADD.W D0,textRect+left(A6) ;include kerning in text rectangle
ADD.W rExtraHang(A6), D2 ;Add in extra for right over hang max
MOVE.W D2,TEXTRECT+RIGHT(A6) ;STORE IN TEXTRECT.RIGHT
MOVE PENLOC(A6),D2 ;GET PNLOC.V
SUB sAscent(A6),D2 ;Use the stack Ascent
MOVE D2,TEXTRECT+TOP(A6) ;TEXTRECT.TOP := PNLOC.V - ASCENT
ADD sHeight(A6),D2 ;Height metric off stack
MOVE D2,TEXTRECT+BOTTOM(A6) ;TEXTRECT.BOTTOM := TOP + HEIGHT
MOVE.L TEXTRECT(A6),TEXTR2(A6) ;MAKE AN EXTRA COPY
MOVE.L TEXTRECT+4(A6),TEXTR2+4(A6) ;OF TEXTRECT IN TEXTR2
ANDI #$0F,CCR ; need to clear 'x' flag
IF hasPenFraction THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals.
add.w d1,pnLocFixed(a0) ; add width fraction to location fraction.
ENDIF
TST PORTBITS+ROWBYTES(A3) ; is it a new port?
BPL.S @useOld ; no, donÕt bother with fraction
ADD D1,pnLocHFrac(A3)
@useOld
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Move pen by the scaled text width
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
SWAP D1 ;Make integer
MOVE PNLOC+H(A3),D0 ;Get the current pen location
ADDX D1,D0 ;New Pen Loc = OldPenLoc + TextWidth
MOVE D0,PNLOC+H(A3) ;Save new pen location
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Quit if the pen is hidden
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST PNVIS(A3) ;IS PNVIS < 0 ?
BLT GOHOME ;YES, QUIT
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END Bounding Rect set up
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Calculate the MinRect
;
; Calc minRect: the intersection of textRect, bitMap bounds,
; clipRgn and visRgn bounding boxes. Quit if no intersection.
; The right bounds of the destination rect is set to the max to allow right kerning
; (Right kerning only works (without trailing spaces) in OR mode.
;
; Registers on Entry:
; A2 = Font Ptr
; A3 = thePort
; A4 = FmOutput record ptr
; A6 = Stack frame
;
; Clobbers:
; A0, A1
; D0, D1, D2, D3
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE textR2+right(A6),-(SP) ;preserve existing right
MOVE #32000,textR2+right(A6) ;get right from other rects
PEA TEXTR2(A6) ;PUSH (MAPPED) TEXTRECT
PEA DSTPIX+BOUNDS(A6) ;PUSH PIXMAP BOUNDS
MOVE.L CLIPRGN(A3),A0 ;GET CLIPRGN HANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
PEA RGNBBOX(A0) ;PUSH CLIPRGN BBOX
MOVE.L VISRGN(A3),A0 ;GET VISRGN HANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
PEA RGNBBOX(A0) ;PUSH VISRGN BBOX
MOVE #4,-(SP) ;PUSH NRECTS=4
PEA MINRECT(A6) ;PUSH DST ADDR
_RSECT ;CALC INTERSECTION
BEQ GOHOME ;QUIT IF NO INTERSECTION
MOVE (SP)+,textR2+right(A6) ;restore text right
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L VISRGN(A3),A1 ;GET VISRGN HANDLE <6> CEL
MOVE.L (A1),A0 ;DE-REFERENCE IT
CMP #10,RGNSIZE(A0) ;IS VISRGN RECTANGULAR ?
BEQ.S @rectRgn ;YES, TAKE FAST OPTIMIZATION
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; All systems go except for VisRgn not rectangular.
; Check if visRgn sect minRect is rectangular.
; IF TrimRect(visRgn,minRect) THEN take the fast way.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L A1,-(SP) ;PUSH VISRGN
PEA MINRECT(A6) ;PUSH MINRECT
MOVE.W #-1, -(SP) ;trim = true for BRUCE
@no32bit
_TRIMRECT ;CALL TRIMRECT
BEQ.S @rectRgn
BLT GOHOME ;quit if intersection empty
ST clipHorz(A6) ;It was clipped so mark it
BRA NOTFAST ;continue if non-rectangular
@rectRgn
;GET VISRGN HANDLE <6> CEL
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Spline Clip Value Set up
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.W MINRECT+TOP(A6),D0 ;GET MINRECT.TOP
SUB.W TEXTRECT+TOP(A6),D0 ;Get Text Top
BLE.S @checkBottom
ST clipVert(A6) ;It was clipped so mark it
SUB.W D0, topClip(A6) ;Adjust the top clipping value
@checkBottom
MOVE.W TEXTRECT+BOTTOM(A6),D0 ;GET MINRECT.BOTTOM
SUB.W MINRECT+BOTTOM(A6),D0 ;Is there clipping
BLE.S @checkHorz ;check horz clip
ST clipVert(A6) ;It was clipped so mark it
ADD.W D0, botClip(A6) ;Adjust the bottom clip
@checkHorz
MOVE.W botClip(A6), origBotClip(A6) ;Init for fakergn check
MOVE.W topClip(A6), origTopClip(A6) ;Init for fakergn check
MOVE.W TEXTRECT+LEFT(A6), D0 ;Get the left
CMP.W MINRECT+LEFT(A6), D0 ;clipped on left???
BGE.S @checkRight ;
ST clipHorz(A6) ;clipping on left
@checkRight
MOVE.W TEXTRECT+RIGHT(A6), D0 ;Get the right
CMP.W MINRECT+RIGHT(A6), D0 ;clipped on right???
BLE.S @doneRight
ST clipHorz(A6) ;clipping on left
@doneRight
TST.B notFastFlag(A6) ;combines the style and stretch checks
BNE NotFast ;NOT FAST
TST.B orMode(A6) ;IS TEXT MODE SRCOR ? (or srcCopy + mask, see above)
BEQ NotFast ;NO, NOT FAST
MOVE.L CLIPRGN(A3),A0 ; Get clip region
MOVE.L (A0),A0 ; Dereference handle
MOVEQ #10,D0
CMP RGNSIZE(A0),D0 ;IS CLIPRGN RECTANGULAR ?
BNE NotFast ;NO, NOT FAST
CMP #1, destDepth(A6) ;****1-bit we can go fast
BEQ.S @depthFast
TST.W clipVert(A6) ;Vertically or horizontally clipped then go do norm loops
BNE NotFast ;check to see if one bit only
@depthFast
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END Calculate the MinRect
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; FAST case Setup
;
; Fast case, go directly to screen.
; If text is clipped vertically, then clear heightflag and update TOPHT
;
; Registers on Entry:
; A2 = Font Ptr
; A3 = thePort
; A4 = FmOutput record ptr
; A6 = Stack frame
;
; Saves & Restores:
; A2
;
; Clobbers:
;
; D0, D1
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
sFAST
MOVEM.L A0-A1/D0-D2,-(SP) ;Save registers
@tryAgain CLR.B -(SP) ;result
MOVE.L A3, -(SP) ;needs the current grafport
_QDDone ;Is accelerator really done and ready for us to blit???
TST.B (SP)+ ;Check result
BEQ.S @tryAgain ;Check until ready!
MOVEM.L (SP)+, A0-A1/D0-D2 ;Restore registers
ST FASTFLAG(A6) ;REMEMBER WE'RE GOING FAST
MOVE sAscent(A6), topAdjust(A6) ;Get ascent into D0
MOVE TEXTRECT+TOP(A6),D0 ;GET DST TOP
SUB DSTPIX+BOUNDS+TOP(A6),D0 ;CONVERT TO GLOBAL COORDINATES
MOVE DSTPIX+ROWBYTES(A6),D1 ;GET ROWBYTES
AND #nuRBMask,D1 ;CLEAR OFF FLAG BITS
MULS D1,D0 ;MULT BY ROWBYTES
ADD.L DSTPIX+BASEADDR(A6),D0 ;ADD START OF DST BITMAP
MOVE.L D0,BUFSTART(A6) ;SET UP BUFSTART FOR LATER
MOVE D1,BUFROW(A6) ;SET UP BUFROW FOR LATER
MOVE DSTPIX+BOUNDS+LEFT(A6),BUFLEFT(A6) ;REMEMBER BUFLEFT
TST.B CRSRFLAG(A6) ;IS DST TO A SCREEN? <BAL 19Sep88>
BEQ @Check32Bit ;=>NO <9Apr90 KON>
PEA MINRECT(A6) ;PUSH SHIELD RECT
MOVE.L REALBOUNDS(A6),-(SP) ;PUSH DELTA FOR GLOBAL
_SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
@Check32Bit
tst.b needs32bit(a6) ;<9Apr90 KON>
beq.s @skip32bit ;<9Apr90 KON>
move.l a3,d0 ;get thePort ptr
_rTranslate24To32 ;mask off high byte BAL/MCF 03Dec88
move.l d0,a3 ;clean thePort ptr
MOVE stackOffset(A6),D1
MOVE.L textPtr(A6),D0 ;GET TEXTPTR
_rTranslate24To32 ;mask off high byte BAL/MCF 03Dec88
MOVE.L d0,textPtr(A6) ;SAVE FOR LATER
moveq #true32b,d0 ;switch to 32 bit addressing
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
move.b d0,MMUsave(a6) ;save previous state for later
@skip32bit
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;
; Get pointers to location table, width table, and height table in font
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.W clipVert(A6) ;Can we try the fast blitting routine???
BNE sGetPtrs ;go to clipping blit loop
fastBlit
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; NEW FAST blit loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Registers Use:
; D0 = scratch A0 = scratch
; D1 = scratch A1 = TextPtr.l
; D2 = shift.w A2 = bitsPtr.l
; D3 = scan.w & nextBand.w(high bit) A3 = glyphArray.l
; D4 = charLoc.l A4 = widTabPtr.l
; D5 = cachePtr.l A5 = DestPtr.l
; D6 = #chars.w A6 = stack frame.l
; D7 = destRowBytes.w A7 = stack pointer.l
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ-
; Figure out Charloc
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ-
MOVE bufLeft(A6),D1 ;get bufleft in register
MOVE penLoc+H(A6),D4 ;Horz pen location
SUB D1,D4 ;charloc relative to the buffer
SWAP D4 ;turn into fixed
TST PORTBITS+ROWBYTES(A3) ;is it a new port?
BPL.S @useOld ;no, set fraction to 1/2
MOVE penLocHFrac(A6),D4 ;set up fractional part
BRA.S @goOn
@useOld
MOVE #$8000,D4 ;Treat so it will round
@goOn
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ-
; Register setup
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ-
MOVEQ #0, D3 ;Init for nextBand to false
MOVE.L cacheHand(A6), A0 ;Handle to the cache
MOVE.L (A0), D0 ;pointer to the cache
_StripAddress ;Make sure it is the right mode
MOVE.L D0, D5 ;save it for later
MOVE.L D0, A0 ;get in address register
LEA cache.glyphArray(A0), A3 ;Get array of glyphs into A0
MOVE.L widthTabHandle,A0 ;point to width table
MOVE.L (A0),A4 ;Save pointer to the width table
MOVE.L textPtr(A6),A1 ;get textPtr
MOVE.W countCopy(A6), D6 ;decrement partial draw character count
SUBQ.W #1,D6 ;make it a DBRA count
MOVE.L bufStart(A6), A5 ;BufStart (dst bitmap)
MOVE.W bufRow(A6), D7 ;Copy of rowbytes
IF HAS_COLOR | SCRIPT_CHAR_EXTRA THEN ;<7> CEL
MOVE.L characterExtra(A6),D1 ;add in character extra, if any
ENDIF
CMP.W #1, destDepth(A6) ;is it 1 deep
BEQ.S @depth1 ;Multi-depth blits
TST.B FastFlag(A6) ;If not fast then do 1-bit to buffer <5>CEL
BEQ.S @depth1 ;do 1-bit
TST.B orMode(A6) ;If not src or then do 1 bit and buffer
BNE deepChar ;It is deep char
@depth1
MOVE.L A6,-(SP) ;REMEMBER Stack frame ptr
BRA.S NextChar
doNextBand
ADDQ.W #1, D6 ;bump count since we are banding
MOVE.L (SP), A6 ;restore stack frame
MOVE.W glyphID(A6), D3 ;put glyphID into d3 for renderIt
BSR renderIt ;Get the glyph
MOVE.L A0, A6 ;restore glyphDataPtr in A6
BEQ gotGlyph ;go blit it
BRA.S skipBand
renderIt1
BTST.L #30, D0 ;Check if there is an error
BNE.S skipChar ;Still an error so skip it
MOVE.W #0, D3
MOVE.L (SP), A6 ;restore stack frame
if (hasDoubleByte) then
move.b highByte(a6),d3 ; load high byte of single byte character
else
move.b -1(a1),d3 ; load single byte character
endif
@render BSR renderIt ;Get the glyph
MOVE.L A0, A6 ;glyphDataPtr in A6
BEQ gotGlyph ;go blit it
skipBand
skipChar
ADD.L 0(A4,D3*4),D4 ;GET FIXED POINT WIDTH
IF HAS_COLOR | SCRIPT_CHAR_EXTRA THEN ;<7> CEL
ADD.L D1,D4 ;add in character extra, if any
ENDIF
BRA.S decCharCount ;continue to nextChar
spaceChar
ADD.L 128(A4), D4 ;Advance a space
decCharCount
SUBQ.W #1, D6
BLT doneStr
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Registers Use:
; D0 = scratch A0 = scratch
; D1 = characterExtra A1 = TextPtr.l
; D2 = shift.w A2 = bitsPtr.l
; D3 = scan.w & nextBand.w(high) A3 = glyphArray.l
; D4 = charLoc.l A4 = widTabPtr.l
; D5 = cachePtr.l A5 = DestPtr.l
; D6 = #chars.w A6 = glyphdataPtr.l
; D7 = destRowBytes.w (A7) = Save a6
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
NextChar
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand ;do the next char band
MOVEQ #0,D3
MOVE.B (A1)+,D3 ;get the next character
if (hasDoubleByte) then
move.l (sp),a6 ; reload the stack frame pointer
move.b d3,highByte(a6) ; save the high byte for later use
clr.b lowByte(a6) ; clear the low byte for now
tst.l encodingTable(a6) ; is this a double byte font?
beq.s @normalFont ; no, skip low byte loading
move.l encodingTable(a6),a0 ; grab pointer to high byte mapping table
tst.b 0(a0,d3.w) ; is this a double byte character?
beq @normalCharacter ; no, skip low byte loading
tst.w d6 ; more bytes left in text?
ble @remapCharacterToNull ; no, remap the high byte
subq.w #1,d6 ; decrement the character count
clr.w d0 ; clear high byte of low word
move.b (a1)+,d0 ; grab the low byte and bump the text pointer
adda.w #256,a0 ; offset to the low byte encoding table
tst.b 0(a0,d0.w) ; is this a valid low byte?
beq @remapCharacterToNull ; no, remap the high byte character
move.b d0,lowByte(a6) ; save the valid low byte for later use
bra @normalCharacter ; continue normally
@remapCharacterToNull
move.b #1,d3 ; remap the high byte character to the missing glyph
move.b d3,highByte(a6) ; save the remapped value in the stack
@normalCharacter
@normalFont
endif
CMP.B #32,D3 ;IS IT A SPACE ?
BEQ.S spaceChar ;Skip the char extra
MOVE.L 0(A3,D3*4),D0 ;Get offset to glyph in D3
BLE.S renderIt1 ;Must render it
ADD.L D5, D0 ;Add in cacheptr address
MOVE.L D0, A6 ;glyphrec = cache + offset
if (hasDoubleByte) then
clr.l d0 ; clear a long for the character code
move.l (sp),a0 ; reload the stack frame pointer
move.b lowByte(a0),d0 ; double byte character?
beq.s @haveGlyphRecord ; no, skip this
move.l 0(a6,d0.w*4),d0 ; load glyph record offset
ble.s renderIt1 ; render if error or not cached
add.l d5,d0 ; convert offset to pointer
move.l d0,a6 ; load glyph record pointer
@haveGlyphRecord
endif
LEA glyph.cacheData(A6), A2 ;Get address
gotGlyph
MOVE.L D4,D2 ;charloc in D2
SWAP D2 ;Just use integer portion
ADD.W glyph.devLSB(A6), D2 ;Get integralized left side bearing
;¥¥¥ spot for skipping advance if char banding!!!
TST.L D3 ;do not advance since the is more of char
BMI.S @skipAdvance ;another band of char
ADD.L 0(A4,D3*4),D4 ;GET FIXED POINT WIDTH
IF HAS_COLOR OR SCRIPT_CHAR_EXTRA THEN ;char extra used in 700 and/or color - not B&W < $700
ADD.L D1,D4 ;add in character extra, if any
ENDIF
@skipAdvance
MOVE.L A5,A0 ;copy of destPtr
MOVE.W glyph.adjustTop(A6), D0 ;Subtract the YMax
MULS.W D7,D0 ;Vertical offset value
ADD.L D0,A0 ;Add in the vert offset
MOVE.W glyph.bitWidth(A6),D3 ;shift count plus width
CMP.W #16,D3 ;bigger than 16?
BGT.S overWord ;We are bigger than a word
MOVE.W D2, D0 ;Use D0 to calc horz dest adjust
LSR.W #4,D0 ;convert to words
ADD.W D0,D0 ;convert to bytes (Horz. offset)
ADD.W D0,A0 ;Add in the horz offset
AND.W #15,D2 ;allow a shift of 0 to 15
ADD.W D2,D3 ;shift + bitwidth
CMP.W #16,D3 ;bigger than 16?
BGT.S bigWord
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; blit loops
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Word Blit
;Regs used:
; D0 = BlitSource.l
; D2 = ShiftAdjust.w
; D3 = Scan.w
; D6 = charNum.w
; D7 = destRow.w
; A0 = DestPtr.l
; A2 = SourcePtr.l
word
MOVE.W glyph.scan(A6), D3 ;Height of character
SUBQ.W #1,D3
@mid MOVE.W (A2)+,D0 ;this particular example is or mode
LSR D2,D0 ;shift into place
OR.W D0,(A0) ;add the bits
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
skipIt DBRA D6,NextChar
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand ;do the next char band
doneStr MOVE.L (SP)+,A6 ;Restore Stack frame ptr
BRA strDone ;no more chars to doÉ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; BigWord Blit
;Regs used:
; D0 = BlitSource.l
; D2 = ShiftAdjust.w
; D3 = Scan.w
; D6 = charNum.w
; D7 = destRow.w
; A0 = DestPtr.l
; A2 = SourcePtr.l
; here, the character spans a word boundary, so must be handled with a long loop on 68K machines
bigWord
MOVE.W glyph.scan(A6), D3 ;Height of character
SUBQ.W #1,D3
@mid MOVE.L (A2),D0 ;this particular example is a or mode
CLR D0 ;clear the low word
LSR.L D2,D0 ;shift into place
OR.L D0,(A0) ;add the bits
ADD.W D7,A0 ;advance to the next dest row
ADDQ #2, A2 ;advance to the next src row
DBRA D3,@mid
DBRA D6,NextChar
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand ;do the next char band
MOVE.L (SP)+,A6 ;Restore Stack frame ptr
BRA strDone ;no more chars to doÉ
OverWord
MOVE.W D2, D0 ;Use D0 to calc horz dest adjust
LSR #5,D0 ;convert to longs
ADD.W D0,D0 ;convert to words (Horz. offset)
ADD.W D0,D0 ;convert to bytes (Horz. offset)
ADD.W D0,A0 ;Add in the horz offset
CMP.W #32,D3 ;bigger than 32?
BGT.S overLong ;Got more than one long
AND.W #31,D2 ;allow a shift of 0 to 31
ADD.W D2, D3 ;shift + bitwidth
CMP.W #32,D3 ;bigger than 32?
BGT.S bigLong ;Shift and width is greater than a long
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; long Blit
;Regs used:
; D0 = BlitSource.l
; D2 = ShiftAdjust.w
; D3 = Scan.w
; D6 = charNum.w
; D7 = destRow.w
; A0 = DestPtr.l
; A2 = SourcePtr.l
; We fit inside a long with the shift
long
MOVE.W glyph.scan(A6), D3 ;Height of character
SUBQ #1,D3
@mid
MOVE.L (A2)+,D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
OR.L D0,(A0) ;add the bits
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
DBRA D6,NextChar
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand ;do the next char band
MOVE.L (SP)+,A6 ;Restore Stack frame ptr
BRA strDone ;no more chars to doÉ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; bigLong Blit
;Regs used:
; D0 = BlitSource.l
; D1 = Left Shift.w
; D2 = Right Shift.w
; D3 = Scan.w
; D6 = charNum.w
; D7 = destRow.w
; A0 = DestPtr.l
; A2 = SourcePtr.l
bigLong
MOVE.L D1, -(SP) ;save d1
MOVE.W glyph.scan(A6), D3 ;Height of character
SUBQ.W #1,D3
MOVE.W #32, D1 ;get number of long bits
SUB.W D2, D1 ;Get the shift next long shift
SUBQ.W #4, D7 ;Advance one long less for dest
@mid
MOVE.L (A2),D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
OR.L D0,(A0)+ ;add the bits
MOVE.L (A2)+,D0 ;get second piece of the long
LSL.L D1,D0 ;shift into place
OR.L D0,(A0) ;Next long
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
ADDQ.W #4, D7 ;restore true value of dest row bytes
MOVE.L (SP)+, D1 ;restore d1
DBRA D6,NextChar
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand ;do the next char band
MOVE.L (SP)+,A6 ;Restore Stack frame ptr
BRA strDone ;no more chars to doÉ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; bigLong Blit
;Regs used:
; D0 = BlitSource.l
; D1 = Left Shift.w
; D2 = Right Shift.w
; D3 = Scan.w
; D5 = longsInScan.w
; D6 = charNum.w & rowBytesAdjust.w
; D7 = destRow.w
; A0 = DestPtr.l
; A2 = SourcePtr.l
; A6 = copy of longsInScan.w
overLong
;Many Longs to move
MOVEM.L D1/D5, -(SP) ;save regs
SWAP D6 ;less longs to advance dest
MOVE.W glyph.scan(A6), D3 ;Height of character
SUBQ.W #1,D3
MOVE.W glyph.byteWidth+2(A6),D6 ;src byte width in D5
SUB.W D6, D7 ;Advance one long less for dest
MOVE.W D6, D5 ;# of src bytes
LSR #2, D5 ;# of longs for inner loop
SUBQ.W #1, D5 ;init for dbra
MOVE.W D5, A6 ;Keep a copy for re-initialization
AND.W #31,D2 ;allow a shift of 0 to 31
MOVE.W #32, D1 ;get number of long bits
SUB.W D2, D1 ;Get the shift next long shift
@mid
MOVE.L (A2),D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
OR.L D0,(A0)+ ;add the bits
MOVE.L (A2)+,D0 ;get second piece of the long
LSL.L D1,D0 ;shift into place
OR.L D0,(A0) ;Next long
DBRA D5,@mid ;# of longs in a scan line
MOVE.W A6, D5 ;# of src bytes
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
ADD.W D6, D7 ;restore true value of dest row bytes
SWAP D6 ;Restore # of chars
MOVEM.L (SP)+, D1/D5 ;restore regs
DBRA D6,NextChar
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand ;do the next char band
MOVE.L (SP)+,A6 ;Restore Stack frame ptr
BRA strDone ;no more chars to doÉ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; MULTI-bit blit routine CHOICE
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Registers Use:
; D0 = scratch A0 = scratch
; D1 = bitdepth A1 = TextPtr.l
; D2 = shift.w A2 = bitsPtr.l
; D3 = scan.w A3 = glyphArray.l
; D4 = charLoc.l A4 = widTabPtr.l
; D5 = char*4.w & longInScan A5 = DestPtr.l
; D6 = #chars.w A6 = stack frame.l
; D7 = destRowBytes.w A7 = stack pointer.l
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
IF 0 THEN
blitJmpTable
DC.W word-blitJmpTable ;0 1-bit blit functions
DC.W bigWord-blitJmpTable ;2
DC.W long-blitJmpTable ;4
DC.W bigLong-blitJmpTable ;6
DC.W overLong-blitJmpTable ;8
DC.W word2-blitJmpTable ;0 2-bit blit functions
DC.W bigWord2-blitJmpTable ;2
DC.W long2-blitJmpTable ;4
DC.W bigLong2-blitJmpTable ;6
DC.W overLong2-blitJmpTable ;8
DC.W word4-blitJmpTable ;0 4-bit blit functions
DC.W bigWord4-blitJmpTable ;2
DC.W long4-blitJmpTable ;4
DC.W bigLong4-blitJmpTable ;6
DC.W overLong4-blitJmpTable ;8
DC.W word8-blitJmpTable ;0 8-bit blit functions
DC.W bigWord8-blitJmpTable ;2
DC.W long8-blitJmpTable ;4
DC.W bigLong8-blitJmpTable ;6
DC.W overLong8-blitJmpTable ;8
DC.W word16-blitJmpTable ;0 16-bit blit functions
DC.W bigWord16-blitJmpTable ;2
DC.W long16-blitJmpTable ;4
DC.W bigLong16-blitJmpTable ;6
DC.W overLong16-blitJmpTable ;8
DC.W word32-blitJmpTable ;0 32-bit blit functions
DC.W bigWord32-blitJmpTable ;2
DC.W long32-blitJmpTable ;4
DC.W bigLong32-blitJmpTable ;6
DC.W overLong32-blitJmpTable ;8
ENDIF
deepChar
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ-
; Set up blit function pointers
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ-
MOVEQ #0, D7 ;
MOVE.W destDepth(A6), D0 ;get depth in D0
CMP.W #8, D0 ;is it 8 deep
BNE @chk2 ;eight deep will not use function ptrs
MOVE.W #3, destShift(A6) ;Shift for multiply
BRA @doneFuncPtrs
@chk2 MOVEQ #-1, D7 ;negate is 1 bit flag for faster check
CMP.W #2, D0 ;is it 2 deep
BNE.S @chk4
MOVE.W #1, destShift(A6) ;Shift for multiply
LEA word2, A0 ;pointer to the function
MOVE.L A0, wordFunc(A6) ;save it away
LEA bigWord2, A0 ;pointer to the function
MOVE.L A0, bigWordFunc(A6) ;save it away
LEA long2, A0 ;pointer to the function
MOVE.L A0, longFunc(A6) ;save it away
LEA bigLong2, A0 ;pointer to the function
MOVE.L A0, bigLongFunc(A6) ;save it away
LEA overLong2, A0 ;pointer to the function
MOVE.L A0, overLongFunc(A6) ;save it away
BRA @doneFuncPtrs
@chk4 CMP.W #4, D0 ;is it 4 deep
BNE.S @chk16
MOVE.W #2, destShift(A6) ;Shift for multiply
LEA word4, A0 ;pointer to the function
MOVE.L A0, wordFunc(A6) ;save it away
LEA bigWord4, A0 ;pointer to the function
MOVE.L A0, bigWordFunc(A6) ;save it away
LEA long4, A0 ;pointer to the function
MOVE.L A0, longFunc(A6) ;save it away
LEA bigLong4, A0 ;pointer to the function
MOVE.L A0, bigLongFunc(A6) ;save it away
LEA overLong4, A0 ;pointer to the function
MOVE.L A0, overLongFunc(A6) ;save it away
BRA @doneFuncPtrs
@chk16 CMP.W #16, D0 ;is it 16 deep
BNE.S @chk32
MOVE.W #4, destShift(A6) ;Shift for multiply
LEA word16, A0 ;pointer to the function
MOVE.L A0, wordFunc(A6) ;save it away
LEA bigWord16, A0 ;pointer to the function
MOVE.L A0, bigWordFunc(A6) ;save it away
LEA long16, A0 ;pointer to the function
MOVE.L A0, longFunc(A6) ;save it away
LEA bigLong16, A0 ;pointer to the function
MOVE.L A0, bigLongFunc(A6) ;save it away
LEA overLong16, A0 ;pointer to the function
MOVE.L A0, overLongFunc(A6) ;save it away
BRA.S @doneFuncPtrs
@chk32 MOVE.W #5, destShift(A6) ;Shift for multiply
LEA word32, A0 ;pointer to the function
MOVE.L A0, wordFunc(A6) ;save it away
LEA bigWord32, A0 ;pointer to the function
MOVE.L A0, bigWordFunc(A6) ;save it away
LEA long32, A0 ;pointer to the function
MOVE.L A0, longFunc(A6) ;save it away
LEA bigLong32, A0 ;pointer to the function
MOVE.L A0, bigLongFunc(A6) ;save it away
LEA overLong32, A0 ;pointer to the function
MOVE.L A0, overLongFunc(A6) ;save it away
@doneFuncPtrs
MOVE.W bufRow(A6), D7 ;Copy of rowbytes
BRA.S NextChar8
doNextBand8
ADDQ.W #1, D6 ;bump count since we are banding
MOVE.W glyphID(A6), D3 ;put glyphID into d3 for renderIt
BSR renderIt ;Get the glyph
BEQ gotGlyph8 ;go blit it
BRA skipIt8
renderIt8
BTST.L #30, D0 ;Check if there is an error
BNE skipChar8 ;Still an error so skip it <57-CEL>
BSR renderIt ;Get the glyph
BEQ gotGlyph8 ;go blit it
skipChar8
ADD.L 0(A4,D3*4),D4 ;Add fixed point width <57-CEL>
ADD.L characterExtra(A6),D4 ;add in character extra, if any
BRA.S decCharCount8 ;continue to nextChar
spaceChar8
ADD.L 128(A4), D4 ;Advance a space
decCharCount8
SUBQ.W #1, D6
BLT strDone
NextChar8
MOVE.W #0,D3
MOVE.B (A1)+,D3 ;get the next character
if (hasDoubleByte) then
move.b d3,highByte(a6) ; save the high byte for later use
clr.b lowByte(a6) ; clear the low byte for now
tst.l encodingTable(a6) ; is this a double byte font?
beq.s @normalFont ; no, skip low byte loading
move.l encodingTable(a6),a0 ; load the encoding table
tst.b 0(a0,d3.w) ; is this a double byte character?
beq.s @normalCharacter ; no, skip low byte loading
tst.w d6 ; more bytes left in text?
ble.s @remapCharacterToNull ; no, remap the high byte
subq.w #1,d6 ; decrement the character count
clr.w d0 ; clear high byte of low word
move.b (a1)+,d0 ; grab the low byte and bump the text pointer
adda.w #256,a0 ; offset to the low byte encoding table
tst.b 0(a0,d0.w) ; is this a valid low byte?
beq @remapCharacterToNull ; no, remap the high byte character
move.b d0,lowByte(a6) ; save the valid low byte for later use
bra @normalCharacter ; continue normally
@remapCharacterToNull
move.b #1,d3 ; remap the high byte character to the missing glyph
move.b d3,highByte(a6) ; save the remapped value in the stack
@normalCharacter
@normalFont
endif
CMP.B #32,D3 ;IS IT A SPACE ?
BEQ spaceChar8 ;Skip the char extra
MOVE.L 0(A3,D3*4),D0 ;Get offset to glyph in D0
BLE renderIt8 ;Must render it
ADD.L D5, D0 ;Add in cacheptr address
MOVE.L D0, A0 ;glyphrec = cache + offset
if (hasDoubleByte) then
clr.l d0 ; clear a long for the character code
move.b lowByte(a6),d0 ; double byte character?
beq.s @haveGlyphRecord ; no, skip this
move.l 0(a0,d0.w*4),d0 ; load glyph record offset
ble renderIt8 ; render if error or not cached
add.l d5,d0 ; convert offset to pointer
move.l d0,a0 ; load glyph record pointer
@haveGlyphRecord
endif
LEA glyph.cacheData(A0), A2 ;Get address
gotGlyph8
MOVE.L D4,D2 ;charloc in D2
SWAP D2 ;Just use integer portion
ADD.W glyph.devLSB(A0), D2 ;Get integralized left side bearing
;¥¥¥ spot for skipping advance if char banding!!!
TST.L D3 ;do not advance since the is more of char
BMI.S @skipAdvance ;another band of char
ADD.L 0(A4,D3*4),D4 ;Add fixed point width
ADD.L characterExtra(A6),D4 ;add in character extra, if any
@skipAdvance
MOVE.W glyph.scan(A0), D3 ;Height of character
SUBQ.W #1,D3
MOVE.W glyph.adjustTop(A0), D0 ;Subtract the YMax
MULS.W D7,D0 ;Vertical offset value
MOVE.W glyph.bitWidth(A0),D1 ;shift count plus width
TST.L D7 ;if negative then multi-bit
BLT notEight ;Multi-depth blits
CMP.W #16,D1 ;bigger than 16?
BGT overWord8 ;We are bigger than a word
MOVEM.L D4/D6, -(SP) ;Save regs
MOVEQ #$F, D4 ;Low 4-bit mask
MOVE.L A5,A0 ;get top screen destination copy
ADD.L D0,A0 ;Add in the vert offset
MOVEQ #0, D0 ;long ready
MOVE.W D2, D0 ;Use D0 to calc horz dest adjust
LSR.W #4,D0 ;convert to words
ADD.W D0,D0 ;convert to bytes (Horz. offset)
MOVE.W destShift(A6), D6 ;Get the destination shift value
LSL.W D6, D0 ;Multiply by dest depth
ADD.W D0,A0 ;Add in the horz offset
AND.W #15,D2 ;allow a shift of 0 to 15
ADD.W D2,D1 ;shift + bitwidth
CMP.W #16,D1 ;bigger than 16?
BGT bigWord8
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;blitting loops
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
word8
ADD.L #12, A0 ;Advance to last long of scan line
@mid MOVE.W (A2)+,D0 ;this particular example is or mode
LSR D2,D0 ;shift into place
MOVE.W D0, D1 ;Get a copy
AND.W D4, D1 ;Get lower four bits
BEQ.S @1 ;nothing to blit
MOVE.L bitTable8(D1*4), D1 ;Add the bits
OR.L D1, (A0) ;Add the bits
@1 LSR.W #4, D0 ;Next four bits
MOVE.W D0, D1 ;Get a copy
AND.W D4, D1 ;Get lower four bits
BEQ.S @2 ;nothing to blit
MOVE.L bitTable8(D1*4), D1 ;Add the bits
OR.L D1, -4(A0) ;Add the bits
@2 LSR.W #4, D0 ;Next four bits
MOVE.B D0, D1 ;Get a copy
AND.W D4, D1 ;Get lower four bits
BEQ.S @3 ;nothing to blit
MOVE.L bitTable8(D1*4), D1 ;Add the bits
OR.L D1, -8(A0) ;Add the bits
@3 LSR.W #4, D0 ;Next four bits
BEQ.S @4 ;nothing to blit
MOVE.L bitTable8(D0*4), D1 ;Add the bits
OR.L D1, -12(A0) ;Add the bits
@4 ADD D7,A0 ;advance to the next dest row
DBRA D3,@mid
MOVEM.L (SP)+, D4/D6 ;Save regs
skipIt8
DBRA D6,NextChar8
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand8 ;do the next char band
BRA strDone ;no more chars to doÉ
MACRO
_blit8long
MOVE.W D0, D1 ;Get a copy
AND.W D4, D1 ;Get lower four bits
BEQ.S @1 ;nothing to blit
MOVE.L 0(A1, D1*4), D1 ;Add the bits
OR.L D1, (A0) ;Add the bits
@1 LSR.W #4, D0 ;Next four bits
MOVE.W D0, D1 ;Get a copy
AND.W D4, D1 ;Get lower four bits
BEQ.S @2 ;nothing to blit
MOVE.L 0(A1, D1*4), D1 ;Add the bits
OR.L D1, -4(A0) ;Add the bits
@2 LSR.W #4, D0 ;Next four bits
MOVE.W D0, D1 ;Get a copy
AND.W D4, D1 ;Get lower four bits
BEQ.S @3 ;nothing to blit
MOVE.L 0(A1, D1*4), D1 ;Add the bits
OR.L D1, -8(A0) ;Add the bits
@3 LSR.W #4, D0 ;Next four bits
BEQ.S @4 ;nothing to blit
MOVE.L 0(A1, D0*4), D1 ;Add the bits
OR.L D1, -12(A0) ;Add the bits
@4 SWAP D0 ;Next four bits
MOVE.W D0, D1 ;Get a copy
AND.W D4, D1 ;Get lower four bits
BEQ.S @5 ;nothing to blit
MOVE.L 0(A1, D1*4), D1 ;Add the bits
OR.L D1, -16(A0) ;Add the bits
@5 LSR.W #4, D0 ;Next four bits
MOVE.W D0, D1 ;Get a copy
AND.W D4, D1 ;Get lower four bits
BEQ.S @6 ;nothing to blit
MOVE.L 0(A1, D1*4), D1 ;Add the bits
OR.L D1, -20(A0) ;Add the bits
@6 LSR.W #4, D0 ;Next four bits
MOVE.W D0, D1 ;Get a copy
AND.W D4, D1 ;Get lower four bits
BEQ.S @7 ;nothing to blit
MOVE.L 0(A1, D1*4), D1 ;Add the bits
OR.L D1, -24(A0) ;Add the bits
@7 LSR.W #4, D0 ;Next four bits
BEQ.S @8 ;nothing to blit
MOVE.L 0(A1, D0*4), D1 ;Add the bits
OR.L D1, -28(A0) ;Add the bits
@8
ENDM
align 4 ;Make long word aligned <54>
bitTable8
DC.L $00000000, $000000FF, $0000FF00, $0000FFFF, $00FF0000, $00FF00FF, $00FFFF00, $00FFFFFF
DC.L $FF000000, $FF0000FF, $FF00FF00, $FF00FFFF, $FFFF0000, $FFFF00FF, $FFFFFF00, $FFFFFFFF
bigWord8
; here, the character spans a word boundary, so must be handled with a long loop on 68K machines
MOVE.L A1, -(SP) ;Save regs
LEA bitTable8, A1 ;Table to the blit longs
ADD.L #28, A0 ;Advance to last long
@mid
MOVE.L (A2),D0 ;this particular example is a copy mode
CLR D0 ;clear the low word
LSR.L D2,D0 ;shift into place
_blit8long ;move src long
ADD D7,A0 ;advance to the next dest row
ADD #2,A2 ;advance to the next src row
DBRA D3,@mid
MOVE.L (SP)+, A1 ;Restore regs
MOVEM.L (SP)+, D4/D6 ;Save regs
DBRA D6,NextChar8
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand8 ;do the next char band
BRA strDone ;no more chars to doÉ
overWord8
CMP.W #32,D1 ;bigger than 32?
BGT overLong8 ;Got more than one long
MOVEM.L D4/D6/D7/A1, -(SP) ;Save regs
MOVEQ #$F, D4 ;Low 4-bit mask
MOVE.L A5,A0 ;get top screen destination copy
ADD.L D0,A0 ;Add in the vert offset
MOVEQ #0, D0 ;long ready
MOVE.W D2, D0 ;Use D0 to calc horz dest adjust
LSR #5,D0 ;convert to longs
ADD.W D0,D0 ;convert to bytes (Horz. offset)
ADD.W D0,D0 ;convert to bytes (Horz. offset)
MOVE.W destShift(A6), D6 ;Get the destination shift value
LSL.W D6, D0 ;Multiply by dest depth
ADD.W D0,A0 ;Add in the horz offset
AND.W #31,D2 ;allow a shift of 0 to 31
ADD.W D2, D1 ;shift + bitwidth
CMP.W #32,D1 ;bigger than 32?
BGT bigLong8 ;Shift and width is greater than a long
; We fit inside a long with the shift
long8
LEA bitTable8, A1 ;Table to the blit longs
ADD.L #28, A0 ;Advance to last long of scan line
@mid
MOVE.L (A2)+,D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
_blit8long ;move src long
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
MOVEM.L (SP)+, D4/D6/D7/A1 ;Restore regs
DBRA D6,NextChar8
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand8 ;do the next char band
BRA strDone ;no more chars to doÉ
bigLong8
MOVE.W #32, D1 ;get number of long bits
SUB.W D2, D1 ;Get the shift next long shift
SWAP D1 ;rightShift in high-word
MOVE D2, D1 ;leftShift in low-word
MOVE.L D1, D2 ;Leave shift in D2
LEA bitTable8, A1 ;Table to the blit longs
ADD.L #28, A0 ;Advance to last long of scan line
SUB.W #32, D7 ;Advance one long less for dest
@mid
MOVE.L (A2),D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
_blit8long ;move src long
SWAP D2 ;get the rightShift
MOVE.L (A2)+,D0 ;get second piece of the long
LSL.L D2,D0 ;shift into place
ADD.W #32, A0 ;next long
_blit8long ;move src long
SWAP D2 ;restore the leftShift
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
MOVEM.L (SP)+, D4/D6/D7/A1 ;Save regs
DBRA D6,NextChar8
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand8 ;do the next char band
BRA strDone ;no more chars to doÉ
overLong8
;Many Longs to move
MOVEM.L D4-D7/A1/A4, -(SP) ;Save regs
MOVEQ #$F, D4 ;Low 4-bit mask
SWAP D6 ;less longs to advance dest
MOVE.W destShift(A6), D1 ;Get the destination shift value
MOVE.W glyph.byteWidth+2(A0),D5 ;# of src bytes
MOVEQ #4, D6 ;Calculate less long adjustment
LSR #2, D5 ;# of longs for inner loop
LSL D1, D6 ;Long less adjustment
MULU D5, D6 ;multiply by number of longs
SUB.W D6, D7 ;Advance one long less for dest
SUBQ.W #1, D5 ;init for dbra
MOVE.W D5, A4 ;Keep a copy for re-initialization
MOVE.L A5,A0 ;get top screen destination copy
ADD.L D0,A0 ;Add in the vert offset
MOVEQ #0, D0 ;long ready
MOVE.W D2, D0 ;Use D0 to calc horz dest adjust
LSR #5,D0 ;convert to longs
ADD.W D0,D0 ;convert to words (Horz. offset)
ADD.W D0,D0 ;convert to bytes (Horz. offset)
LSL.W D1, D0 ;Multiply by dest depth
ADD.W D0,A0 ;Add in the horz offset
AND.W #31,D2 ;allow a shift of 0 to 31
MOVE.W #32, D1 ;get number of long bits
SUB.W D2, D1 ;Get the shift next long shift
SWAP D1 ;rightShift in high-word
MOVE D2, D1 ;leftShift in low-word
MOVE.L D1, D2 ;Leave shift in D2
LEA bitTable8, A1 ;Table to the blit longs
ADD.L #28, A0 ;Advance to last long of scan line
@mid
MOVE.L (A2),D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
_blit8long ;move src long
SWAP D2 ;get the rightShift
MOVE.L (A2)+,D0 ;get second piece of the long
LSL.L D2,D0 ;shift into place
ADD.W #32, A0 ;next long
_blit8long ;move src long
SWAP D2 ;restore the leftShift
DBRA D5,@mid ;# of longs in a scan line
MOVE.W A4, D5 ;# of src bytes
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
ADD.W D6, D7 ;Next row
MOVEM.L (SP)+, D4-D7/A1/A4 ;Save regs
DBRA D6,NextChar8
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand8 ;do the next char band
BRA strDone ;no more chars to doÉ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Not eight bit but it is multi bit
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
notEight
MOVEM.L D4-D7/A1/A4, -(SP) ;Save regs
CMP.W #16,D1 ;bigger than 16?
BGT.S @overWord ;We are bigger than a word
MOVE.L A5,A0 ;get top screen destination copy
ADD.L D0,A0 ;Add in the vert offset
MOVEQ #0, D0 ;long ready
MOVE.W D2, D0 ;Use D0 to calc horz dest adjust
LSR.W #4,D0 ;convert to words
ADD.W D0,D0 ;convert to bytes (Horz. offset)
MOVE.W destShift(A6), D6 ;Get the destination shift value
LSL.W D6, D0 ;Multiply by dest depth
ADD.W D0,A0 ;Add in the horz offset
AND.W #15,D2 ;allow a shift of 0 to 15
ADD.W D2,D1 ;shift + bitwidth
CMP.W #16,D1 ;bigger than 16?
BGT.S @bigWord
MOVE.L wordFunc(A6), A1 ;point to blit function
BRA @blitIt
@bigWord
MOVE.L bigWordFunc(A6), A1 ;point to blit function
BRA @blitIt
@overWord
CMP.W #32,D1 ;bigger than 32?
BGT.S @overLong ;Got more than one long
MOVE.L A5,A0 ;get top screen destination copy
ADD.L D0,A0 ;Add in the vert offset
MOVEQ #0, D0 ;long ready
MOVE.W D2, D0 ;Use D0 to calc horz dest adjust
LSR #5,D0 ;convert to longs
ADD.W D0,D0 ;convert to bytes (Horz. offset)
ADD.W D0,D0 ;convert to bytes (Horz. offset)
MOVE.W destShift(A6), D6 ;Get the destination shift value
LSL.W D6, D0 ;Multiply by dest depth
ADD.W D0,A0 ;Add in the horz offset
AND.W #31,D2 ;allow a shift of 0 to 31
ADD.W D2, D1 ;shift + bitwidth
CMP.W #32,D1 ;bigger than 32?
BGT.S @bigLong ;Shift and width is greater than a long
MOVE.L longFunc(A6), A1 ;point to blit function
BRA.S @blitIt
@bigLong
MOVE.W #32, D1 ;get number of long bits
SUB.W D2, D1 ;Get the shift next long shift
SWAP D1 ;rightShift in high-word
MOVE D2, D1 ;leftShift in low-word
MOVE.L D1, D2 ;Leave shift in D2
MOVE.L bigLongFunc(A6), A1 ;point to blit function
BRA.S @blitIt
@overLong
SWAP D6 ;less longs to advance dest
MOVE.W destShift(A6), D1 ;Get the destination shift value
MOVE.W glyph.byteWidth+2(A0),D5 ;# of src bytes
MOVEQ #4, D6 ;Calculate less long adjustment
LSR #2, D5 ;# of longs for inner loop
LSL D1, D6 ;Long less adjustment
MULU D5, D6 ;multiply by number of longs
SUB.W D6, D7 ;Advance one long less for dest
SUBQ.W #1, D5 ;init for dbra
MOVE.W D5, A4 ;Keep a copy for re-initialization
MOVE.L A5,A0 ;get top screen destination copy
ADD.L D0,A0 ;Add in the vert offset
MOVEQ #0, D0 ;long ready
MOVE.W D2, D0 ;Use D0 to calc horz dest adjust
LSR #5,D0 ;convert to longs
ADD.W D0,D0 ;convert to words (Horz. offset)
ADD.W D0,D0 ;convert to bytes (Horz. offset)
LSL.W D1, D0 ;Multiply by dest depth
ADD.W D0,A0 ;Add in the horz offset
AND.W #31,D2 ;allow a shift of 0 to 31
MOVE.W #32, D1 ;get number of long bits
SUB.W D2, D1 ;Get the shift next long shift
SWAP D1 ;rightShift in high-word
MOVE D2, D1 ;leftShift in low-word
MOVE.L D1, D2 ;Leave shift in D2
MOVE.L overLongFunc(A6), A1 ;point to blit function
@blitIt
JSR (A1) ;go blit it
MOVEM.L (SP)+, D4-D7/A1/A4 ;Save regs
DBRA D6,NextChar8
TST.L D3 ;another char band then call retrieve!!!
BMI.S doNextBand8 ;do the next char band
BRA strDone ;no more chars to doÉ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; 2-bit NEW FAST blit loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Registers Use:
; D0 = scratch A0 = scratch
; D1 = scratch A1 = TextPtr.l
; D2 = shift.w A2 = bitsPtr.l
; D3 = scan.w A3 = glyphArray.l
; D4 = charLoc.l A4 = widTabPtr.l
; D5 = char*4.w A5 = DestPtr.l
; D6 = #chars.w A6 = stack frame.l
; D7 = rowBytes.w A7 = stack pointer.l
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
align 4 ;Make long word aligned <54>
Table2
DC $0000,$0003,$000c,$000f,$0030,$0033,$003c,$003f
DC $00c0,$00c3,$00cc,$00cf,$00f0,$00f3,$00fc,$00ff
DC $0300,$0303,$030c,$030f,$0330,$0333,$033c,$033f
DC $03c0,$03c3,$03cc,$03cf,$03f0,$03f3,$03fc,$03ff
DC $0c00,$0c03,$0c0c,$0c0f,$0c30,$0c33,$0c3c,$0c3f
DC $0cc0,$0cc3,$0ccc,$0ccf,$0cf0,$0cf3,$0cfc,$0cff
DC $0f00,$0f03,$0f0c,$0f0f,$0f30,$0f33,$0f3c,$0f3f
DC $0fc0,$0fc3,$0fcc,$0fcf,$0ff0,$0ff3,$0ffc,$0fff
DC $3000,$3003,$300c,$300f,$3030,$3033,$303c,$303f
DC $30c0,$30c3,$30cc,$30cf,$30f0,$30f3,$30fc,$30ff
DC $3300,$3303,$330c,$330f,$3330,$3333,$333c,$333f
DC $33c0,$33c3,$33cc,$33cf,$33f0,$33f3,$33fc,$33ff
DC $3c00,$3c03,$3c0c,$3c0f,$3c30,$3c33,$3c3c,$3c3f
DC $3cc0,$3cc3,$3ccc,$3ccf,$3cf0,$3cf3,$3cfc,$3cff
DC $3f00,$3f03,$3f0c,$3f0f,$3f30,$3f33,$3f3c,$3f3f
DC $3fc0,$3fc3,$3fcc,$3fcf,$3ff0,$3ff3,$3ffc,$3fff
DC $c000,$c003,$c00c,$c00f,$c030,$c033,$c03c,$c03f
DC $c0c0,$c0c3,$c0cc,$c0cf,$c0f0,$c0f3,$c0fc,$c0ff
DC $c300,$c303,$c30c,$c30f,$c330,$c333,$c33c,$c33f
DC $c3c0,$c3c3,$c3cc,$c3cf,$c3f0,$c3f3,$c3fc,$c3ff
DC $cc00,$cc03,$cc0c,$cc0f,$cc30,$cc33,$cc3c,$cc3f
DC $ccc0,$ccc3,$cccc,$cccf,$ccf0,$ccf3,$ccfc,$ccff
DC $cf00,$cf03,$cf0c,$cf0f,$cf30,$cf33,$cf3c,$cf3f
DC $cfc0,$cfc3,$cfcc,$cfcf,$cff0,$cff3,$cffc,$cfff
DC $f000,$f003,$f00c,$f00f,$f030,$f033,$f03c,$f03f
DC $f0c0,$f0c3,$f0cc,$f0cf,$f0f0,$f0f3,$f0fc,$f0ff
DC $f300,$f303,$f30c,$f30f,$f330,$f333,$f33c,$f33f
DC $f3c0,$f3c3,$f3cc,$f3cf,$f3f0,$f3f3,$f3fc,$f3ff
DC $fc00,$fc03,$fc0c,$fc0f,$fc30,$fc33,$fc3c,$fc3f
DC $fcc0,$fcc3,$fccc,$fccf,$fcf0,$fcf3,$fcfc,$fcff
DC $ff00,$ff03,$ff0c,$ff0f,$ff30,$ff33,$ff3c,$ff3f
DC $ffc0,$ffc3,$ffcc,$ffcf,$fff0,$fff3,$fffc,$ffff
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;blitting loops
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MACRO
_blitWord2
MOVE.B D0,D4 ;Get a copy
LSR.W #8,D0 ;Next four bits
MOVE.L 0(A1,D0*2),D0 ;Add the bits
MOVE.W 0(A1,D4*2),D0 ;Add the bits
OR.L D0,(A0) ;Add the bits
ENDM
MACRO
_blitLong2
MOVE.B D0,D4
LSR.W #8,D0 ;Next bytes worth
MOVE.L 0(A1,D0*2),D1 ;get the bits
MOVE.W 0(A1,D4*2),D1 ;get the next word
OR.L D1,(A0) ;Add the bits
SWAP D0 ;High Word
MOVE.B D0,D4
LSR.W #8,D0 ;Next bytes worth
MOVE.L 0(A1,D0*2),D1 ;get the bits
MOVE.W 0(A1,D4*2),D1 ;get the next word
OR.L D1,-4(A0) ;Add the bits
ENDM
word2 LEA table2, A1 ;Table to the blit longs
MOVEQ #0, D4 ;ready for blitloop
@mid MOVE.W (A2)+,D0 ;this particular example is or mode
LSR D2,D0 ;shift into place
_blitWord2
ADD D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
bigWord2
; here, the character spans a word boundary, so must be handled with a long loop on 68K machines
MOVEQ #0, D4 ;ready for blitloop
LEA table2, A1 ;Table to the blit longs
ADD.L #4, A0 ;Advance to last long of scan line
@mid2
MOVE.L (A2),D0 ;this particular example is a copy mode
CLR D0 ;clear the low word
LSR.L D2,D0 ;shift into place
_blitLong2 ;blit one source long to dest
ADD D7,A0 ;advance to the next dest row
ADD #2,A2 ;advance to the next src row
DBRA D3,@mid2
RTS
long2
; We fit inside a long with the shift
MOVEQ #0, D4 ;ready for blitloop
LEA table2, A1 ;Table to the blit longs
ADD.L #4, A0 ;Advance to last long of scan line
@mid
MOVE.L (A2)+,D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
_blitLong2 ;blit one source long to dest
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
bigLong2
MOVEQ #0, D4 ;ready for blitloop
LEA table2, A1 ;Table to the blit longs
ADD.L #4, A0 ;Advance to last long of scan line
SUBQ.W #8, D7 ;Advance one long less for dest
@mid
MOVE.L (A2),D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
_blitLong2 ;blit one source long to dest
SWAP D2 ;get the rightShift
MOVE.L (A2)+,D0 ;get second piece of the long
LSL.L D2,D0 ;shift into place
ADDQ.W #8, A0 ;next long
_blitLong2 ;blit one source long to dest
SWAP D2 ;restore the leftShift
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
overLong2
;Many Longs to move
MOVEQ #0, D4 ;ready for blitloop
LEA table2, A1 ;Table to the blit longs
ADD.L #4, A0 ;Advance to last long of scan line
@mid MOVE.L (A2),D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
_blitLong2 ;blit one source long to dest
SWAP D2 ;get the rightShift
ADDQ.W #8, A0 ;next long
MOVE.L (A2)+,D0 ;get second piece of the long
LSL.L D2,D0 ;shift into place
_blitLong2 ;blit one source long to dest
SWAP D2 ;restore the leftShift
DBRA D5,@mid ;# of longs in a scan line
MOVE.W A4, D5 ;# of src bytes
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
ADD.W D6,D7 ;re-adjust the rowbytes to itÕs original value
SWAP D6 ;Restore # of chars
RTS
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; End 2-bit NEW FAST blit loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; 4-bit NEW FAST blit loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Registers Use:
; D0 = scratch A0 = scratch
; D1 = scratch A1 = TextPtr.l
; D2 = shift.w A2 = bitsPtr.l
; D3 = scan.w A3 = glyphArray.l
; D4 = charLoc.l A4 = widTabPtr.l
; D5 = char*4.w A5 = DestPtr.l
; D6 = #chars.w A6 = stack frame.l
; D7 = rowBytes.w A7 = stack pointer.l
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;blitting loops
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
align 4 ;Make long word aligned <54>
TABLE4 DC.L $00000000,$0000000F,$000000F0,$000000FF ;QUADRUPLING TABLE
DC.L $00000F00,$00000F0F,$00000FF0,$00000FFF
DC.L $0000F000,$0000F00F,$0000F0F0,$0000F0FF
DC.L $0000FF00,$0000FF0F,$0000FFF0,$0000FFFF
DC.L $000F0000,$000F000F,$000F00F0,$000F00FF ;QUADRUPLING TABLE
DC.L $000F0F00,$000F0F0F,$000F0FF0,$000F0FFF
DC.L $000FF000,$000FF00F,$000FF0F0,$000FF0FF
DC.L $000FFF00,$000FFF0F,$000FFFF0,$000FFFFF
DC.L $00F00000,$00F0000F,$00F000F0,$00F000FF ;QUADRUPLING TABLE
DC.L $00F00F00,$00F00F0F,$00F00FF0,$00F00FFF
DC.L $00F0F000,$00F0F00F,$00F0F0F0,$00F0F0FF
DC.L $00F0FF00,$00F0FF0F,$00F0FFF0,$00F0FFFF
DC.L $00FF0000,$00FF000F,$00FF00F0,$00FF00FF ;QUADRUPLING TABLE
DC.L $00FF0F00,$00FF0F0F,$00FF0FF0,$00FF0FFF
DC.L $00FFF000,$00FFF00F,$00FFF0F0,$00FFF0FF
DC.L $00FFFF00,$00FFFF0F,$00FFFFF0,$00FFFFFF
DC.L $0F000000,$0F00000F,$0F0000F0,$0F0000FF ;QUADRUPLING TABLE
DC.L $0F000F00,$0F000F0F,$0F000FF0,$0F000FFF
DC.L $0F00F000,$0F00F00F,$0F00F0F0,$0F00F0FF
DC.L $0F00FF00,$0F00FF0F,$0F00FFF0,$0F00FFFF
DC.L $0F0F0000,$0F0F000F,$0F0F00F0,$0F0F00FF ;QUADRUPLING TABLE
DC.L $0F0F0F00,$0F0F0F0F,$0F0F0FF0,$0F0F0FFF
DC.L $0F0FF000,$0F0FF00F,$0F0FF0F0,$0F0FF0FF
DC.L $0F0FFF00,$0F0FFF0F,$0F0FFFF0,$0F0FFFFF
DC.L $0FF00000,$0FF0000F,$0FF000F0,$0FF000FF ;QUADRUPLING TABLE
DC.L $0FF00F00,$0FF00F0F,$0FF00FF0,$0FF00FFF
DC.L $0FF0F000,$0FF0F00F,$0FF0F0F0,$0FF0F0FF
DC.L $0FF0FF00,$0FF0FF0F,$0FF0FFF0,$0FF0FFFF
DC.L $0FFF0000,$0FFF000F,$0FFF00F0,$0FFF00FF ;QUADRUPLING TABLE
DC.L $0FFF0F00,$0FFF0F0F,$0FFF0FF0,$0FFF0FFF
DC.L $0FFFF000,$0FFFF00F,$0FFFF0F0,$0FFFF0FF
DC.L $0FFFFF00,$0FFFFF0F,$0FFFFFF0,$0FFFFFFF
DC.L $F0000000,$F000000F,$F00000F0,$F00000FF ;QUADRUPLING TABLE
DC.L $F0000F00,$F0000F0F,$F0000FF0,$F0000FFF
DC.L $F000F000,$F000F00F,$F000F0F0,$F000F0FF
DC.L $F000FF00,$F000FF0F,$F000FFF0,$F000FFFF
DC.L $F00F0000,$F00F000F,$F00F00F0,$F00F00FF ;QUADRUPLING TABLE
DC.L $F00F0F00,$F00F0F0F,$F00F0FF0,$F00F0FFF
DC.L $F00FF000,$F00FF00F,$F00FF0F0,$F00FF0FF
DC.L $F00FFF00,$F00FFF0F,$F00FFFF0,$F00FFFFF
DC.L $F0F00000,$F0F0000F,$F0F000F0,$F0F000FF ;QUADRUPLING TABLE
DC.L $F0F00F00,$F0F00F0F,$F0F00FF0,$F0F00FFF
DC.L $F0F0F000,$F0F0F00F,$F0F0F0F0,$F0F0F0FF
DC.L $F0F0FF00,$F0F0FF0F,$F0F0FFF0,$F0F0FFFF
DC.L $F0FF0000,$F0FF000F,$F0FF00F0,$F0FF00FF ;QUADRUPLING TABLE
DC.L $F0FF0F00,$F0FF0F0F,$F0FF0FF0,$F0FF0FFF
DC.L $F0FFF000,$F0FFF00F,$F0FFF0F0,$F0FFF0FF
DC.L $F0FFFF00,$F0FFFF0F,$F0FFFFF0,$F0FFFFFF
DC.L $FF000000,$FF00000F,$FF0000F0,$FF0000FF ;QUADRUPLING TABLE
DC.L $FF000F00,$FF000F0F,$FF000FF0,$FF000FFF
DC.L $FF00F000,$FF00F00F,$FF00F0F0,$FF00F0FF
DC.L $FF00FF00,$FF00FF0F,$FF00FFF0,$FF00FFFF
DC.L $FF0F0000,$FF0F000F,$FF0F00F0,$FF0F00FF ;QUADRUPLING TABLE
DC.L $FF0F0F00,$FF0F0F0F,$FF0F0FF0,$FF0F0FFF
DC.L $FF0FF000,$FF0FF00F,$FF0FF0F0,$FF0FF0FF
DC.L $FF0FFF00,$FF0FFF0F,$FF0FFFF0,$FF0FFFFF
DC.L $FFF00000,$FFF0000F,$FFF000F0,$FFF000FF ;QUADRUPLING TABLE
DC.L $FFF00F00,$FFF00F0F,$FFF00FF0,$FFF00FFF
DC.L $FFF0F000,$FFF0F00F,$FFF0F0F0,$FFF0F0FF
DC.L $FFF0FF00,$FFF0FF0F,$FFF0FFF0,$FFF0FFFF
DC.L $FFFF0000,$FFFF000F,$FFFF00F0,$FFFF00FF ;QUADRUPLING TABLE
DC.L $FFFF0F00,$FFFF0F0F,$FFFF0FF0,$FFFF0FFF
DC.L $FFFFF000,$FFFFF00F,$FFFFF0F0,$FFFFF0FF
DC.L $FFFFFF00,$FFFFFF0F,$FFFFFFF0,$FFFFFFFF
MACRO
_Blit4word
MOVE.B D0,D4
BEQ.S @1
MOVE.L 0(A1,D4*4),D1
OR.L D1,(A0)
@1 LSR.W #8,D0
BEQ.S @2
MOVE.L 0(A1,D0*4),D1
OR.L D1,-4(A0)
@2
ENDM
MACRO
_Blit4long ;move src long
MOVE.B D0, D4 ;Get a copy
BEQ.S @1 ;nothing to blit
MOVE.L 0(A1,D4*4), D1 ;Add the bits
OR.L D1, (A0) ;Add the bits
@1 LSR.W #8, D0 ;Next four bits
BEQ.S @2 ;nothing to blit
MOVE.L 0(A1,D0*4), D1 ;Add the bits
OR.L D1, -4(A0) ;Add the bits
@2 SWAP D0
MOVE.B D0, D4 ;Get a copy
BEQ.S @3 ;nothing to blit
MOVE.L 0(A1,D4*4), D1 ;Add the bits
OR.L D1, -8(A0) ;Add the bits
@3 LSR.W #8, D0 ;Next four bits
BEQ.S @4 ;nothing to blit
MOVE.L 0(A1,D0*4), D1 ;Add the bits
OR.L D1, -12(A0) ;Add the bits
@4
ENDM
word4 MOVEQ #0, D4 ;ready for blit macro
LEA table4, A1 ;Table to the blit longs
ADD.L #4 , A0 ;Advance to last long of scan line
@mid MOVE.W (A2)+,D0 ;this particular example is or mode
LSR.W D2,D0 ;shift into place
_Blit4word
ADD D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
bigWord4
; here, the character spans a word boundary, so must be handled with a long loop on 68K machines
MOVEQ #0, D4 ;ready for blit macro
LEA table4, A1 ;Table to the blit longs
ADD.L #12, A0 ;Advance to last long of scan line
@mid2
MOVE.L (A2),D0 ;this particular example is a copy mode
CLR D0 ;clear the low word
LSR.L D2,D0 ;shift into place
_Blit4long ;move src long
ADD D7,A0 ;advance to the next dest row
ADD #2,A2 ;advance to the next src row
DBRA D3,@mid2
RTS
long4
; We fit inside a long with the shift
MOVEQ #0, D4 ;ready for blit macro
LEA table4, A1 ;Table to the blit longs
ADD.L #12, A0 ;Advance to last long of scan line
@mid
MOVE.L (A2)+,D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
_Blit4long ;move src long
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
bigLong4
MOVEQ #0, D4 ;ready for blit macro
LEA table4, A1 ;Table to the blit longs
ADD.L #12, A0 ;Advance to last long of scan line
SUB.W #16, D7 ;Advance one long less for dest
@mid
MOVE.L (A2),D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
_Blit4long ;move src long
SWAP D2 ;get the rightShift
MOVE.L (A2)+,D0 ;get second piece of the long
LSL.L D2,D0 ;shift into place
ADD.W #16, A0 ;next long
_Blit4long ;move src long
SWAP D2 ;restore the leftShift
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
overLong4
;Many Longs to move
MOVEQ #0, D4 ;ready for blit macro
LEA table4, A1 ;Table to the blit longs
ADD.L #12, A0 ;Advance to last long of scan line
@mid
MOVE.L (A2),D0 ;this particular example is a or mode
LSR.L D2,D0 ;shift into place
_Blit4long ;move src long
SWAP D2 ;get the rightShift
ADD.W #16, A0 ;next long
MOVE.L (A2)+,D0 ;get second piece of the long
LSL.L D2,D0 ;shift into place
_Blit4long ;move src long
SWAP D2 ;restore the leftShift
DBRA D5,@mid ;# of longs in a scan line
MOVE.W A4, D5 ;# of src bytes
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
ADD.W D6, D7 ;restore true value of dest row bytes
SWAP D6 ;Restore # of chars
RTS
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; End 4-bit NEW FAST blit loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; 16-bit NEW FAST blit loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Registers Use:
; D0 = scratch A0 = scratch
; D1 = scratch A1 = TextPtr.l
; D2 = shift.w A2 = bitsPtr.l
; D3 = scan.w A3 = glyphArray.l
; D4 = charLoc.l A4 = widTabPtr.l
; D5 = char*4.w A5 = DestPtr.l
; D6 = #chars.w A6 = stack frame.l
; D7 = rowBytes.w A7 = stack pointer.l
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;blitting loops
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MACRO
_blit16word
MOVEQ #1, D4 ;for inner loop
@inner ADDX.W D0,D0 ;if extended then blit
BCC.S @1
MOVE.W D1, (A0) ;Make 16-bit black bit
@1 ADDX.W D0,D0 ;if extended then blit
BCC.S @2
MOVE.W D1, 2(A0) ;Make 16-bit black bit
@2 ADDX.W D0,D0 ;if extended then blit
BCC.S @3
MOVE.W D1, 4(A0) ;Make 16-bit black bit
@3 ADDX.W D0,D0 ;if extended then blit
BCC.S @4
MOVE.W D1, 6(A0) ;Make 16-bit black bit
@4 ADDX.W D0,D0 ;if extended then blit
BCC.S @5
MOVE.W D1, 8(A0) ;Make 16-bit black bit
@5 ADDX.W D0,D0 ;if extended then blit
BCC.S @6
MOVE.W D1, 10(A0) ;Make 16-bit black bit
@6 ADDX.W D0,D0 ;if extended then blit
BCC.S @7
MOVE.W D1, 12(A0) ;Make 16-bit black bit
@7 ADDX.W D0,D0 ;if extended then blit
BCC.S @8
MOVE.W D1, 14(A0) ;Make 16-bit black bit
@8 ADD #16, A0 ;Bump to next set
DBRA D4,@inner
ENDM
MACRO
_blit16long
MOVEQ #3, D4 ;for inner loop
@inner ADDX.L D0,D0 ;if extended then blit
BCC.S @1
MOVE.W D1, (A0) ;Make 16-bit black bit
@1 ADDX.L D0,D0 ;if extended then blit
BCC.S @2
MOVE.W D1, 2(A0) ;Make 16-bit black bit
@2 ADDX.L D0,D0 ;if extended then blit
BCC.S @3
MOVE.W D1, 4(A0) ;Make 16-bit black bit
@3 ADDX.L D0,D0 ;if extended then blit
BCC.S @4
MOVE.W D1, 6(A0) ;Make 16-bit black bit
@4 ADDX.L D0,D0 ;if extended then blit
BCC.S @5
MOVE.W D1, 8(A0) ;Make 16-bit black bit
@5 ADDX.L D0,D0 ;if extended then blit
BCC.S @6
MOVE.W D1, 10(A0) ;Make 16-bit black bit
@6 ADDX.L D0,D0 ;if extended then blit
BCC.S @7
MOVE.W D1, 12(A0) ;Make 16-bit black bit
@7 ADDX.L D0,D0 ;if extended then blit
BCC.S @8
MOVE.W D1, 14(A0) ;Make 16-bit black bit
@8 ADD #16, A0 ;Bump to next set
DBRA D4,@inner
ENDM
bigWord16
word16 SUB.W #32,D7 ;adjust the rowbytes for loop
ADD.W D2,D2 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
ADD.W D2,A0 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
MOVEQ #0,D1 ;for dest black
@mid MOVE.W (A2)+,D0 ;this particular example is or mode
_blit16word ;Blit the bits
ADD D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
bigLong16
long16 SUB.W #64,D7 ;adjust the rowbytes for loop
ADD.W D2,D2 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
ADD.W D2,A0 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
MOVEQ #0,D1 ;for dest black
@mid MOVE.L (A2)+,D0 ;this particular example is a or mode
_blit16long ;Blit the bits
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
overLong16
ADD.W D2,D2 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
ADD.W D2,A0 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
MOVEQ #0,D1 ;for dest black
@mid MOVE.L (A2)+,D0 ;this particular example is a or mode
BEQ.S @skip
_blit16long ;Blit the bits
DBRA D5,@mid ;# of longs in a scan line
MOVE.W A4,D5 ;# of src bytes
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
@skip ADD.W #64,A0
DBRA D5,@mid ;# of longs in a scan line
MOVE.W A4,D5 ;# of src bytes
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END 16-bit NEW FAST blit loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; 32-bit NEW FAST blit loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Registers Use:
; D0 = scratch A0 = scratch
; D1 = scratch A1 = TextPtr.l
; D2 = shift.w A2 = bitsPtr.l
; D3 = scan.w A3 = glyphArray.l
; D4 = charLoc.l A4 = widTabPtr.l
; D5 = char*4.w A5 = DestPtr.l
; D6 = #chars.w A6 = stack frame.l
; D7 = rowBytes.w A7 = stack pointer.l
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;blitting loops
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MACRO
_blit32word
MOVEQ #1, D4 ;for inner loop
@inner ADDX.W D0,D0 ;if extended then blit
BCC.S @1
MOVE.L D1, (A0) ;Make 16-bit black bit
@1 ADDX.W D0,D0 ;if extended then blit
BCC.S @2
MOVE.L D1, 4(A0) ;Make 16-bit black bit
@2 ADDX.W D0,D0 ;if extended then blit
BCC.S @3
MOVE.L D1, 8(A0) ;Make 16-bit black bit
@3 ADDX.W D0,D0 ;if extended then blit
BCC.S @4
MOVE.L D1, 12(A0) ;Make 16-bit black bit
@4 ADDX.W D0,D0 ;if extended then blit
BCC.S @5
MOVE.L D1, 16(A0) ;Make 16-bit black bit
@5 ADDX.W D0,D0 ;if extended then blit
BCC.S @6
MOVE.L D1, 20(A0) ;Make 16-bit black bit
@6 ADDX.W D0,D0 ;if extended then blit
BCC.S @7
MOVE.L D1, 24(A0) ;Make 16-bit black bit
@7 ADDX.W D0,D0 ;if extended then blit
BCC.S @8
MOVE.L D1, 28(A0) ;Make 16-bit black bit
@8 ADD #32, A0 ;Bump to next set
DBRA D4,@inner
ENDM
MACRO
_blit32long
MOVEQ #3, D4 ;for inner loop
@inner ADDX.L D0,D0 ;if extended then blit
BCC.S @1
MOVE.L D1, (A0) ;Make 16-bit black bit
@1 ADDX.L D0,D0 ;if extended then blit
BCC.S @2
MOVE.L D1, 4(A0) ;Make 16-bit black bit
@2 ADDX.L D0,D0 ;if extended then blit
BCC.S @3
MOVE.L D1, 8(A0) ;Make 16-bit black bit
@3 ADDX.L D0,D0 ;if extended then blit
BCC.S @4
MOVE.L D1, 12(A0) ;Make 16-bit black bit
@4 ADDX.L D0,D0 ;if extended then blit
BCC.S @5
MOVE.L D1, 16(A0) ;Make 16-bit black bit
@5 ADDX.L D0,D0 ;if extended then blit
BCC.S @6
MOVE.L D1, 20(A0) ;Make 16-bit black bit
@6 ADDX.L D0,D0 ;if extended then blit
BCC.S @7
MOVE.L D1, 24(A0) ;Make 16-bit black bit
@7 ADDX.L D0,D0 ;if extended then blit
BCC.S @8
MOVE.L D1, 28(A0) ;Make 16-bit black bit
@8 ADD #32, A0 ;Bump to next set
DBRA D4,@inner
ENDM
bigWord32
word32 SUB.W #64,D7 ;adjust the rowbytes for loop
LSL.W #2,D2 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
ADD.W D2,A0 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
MOVEQ #0, D1 ;for dest black
@mid MOVE.W (A2)+,D0 ;this particular example is or mode
_blit32word ;Blit the bits
ADD D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
bigLong32
long32 SUB.W #128,D7 ;adjust the rowbytes for loop
LSL.W #2,D2 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
ADD.W D2,A0 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
MOVEQ #0,D1 ;for dest black
@mid MOVE.L (A2)+,D0 ;this particular example is a or mode
_blit32long ;Blit the bits
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
overLong32
LSL.W #2,D2 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
ADD.W D2,A0 ;NOT NEEDED AFTER SHIFT ADJUSTMENTS MADE ABOVE
MOVEQ #0,D1 ;for dest black
@mid MOVE.L (A2)+,D0 ;this particular example is a or mode
BEQ.S @skip
_blit32long ;Blit the bits
DBRA D5,@mid ;# of longs in a scan line
MOVE.W A4,D5 ;# of src bytes
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
@skip ADD.W #128,A0
DBRA D5,@mid ;# of longs in a scan line
MOVE.W A4,D5 ;# of src bytes
ADD.W D7,A0 ;advance to the next dest row
DBRA D3,@mid
RTS
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END 32-bit NEW FAST blit loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; CACHE RETRIEVAL
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Input:
; D3 = glyphID
;
renderIt
MOVEM.L A1/D0-D2,-(SP) ;Save off all registers before JSR
SUBQ #4,SP ;make room for result
MOVE.W D3, glyphID(A6) ;put glyphID into sp_Glyph
if (hasDoubleByte) then
tst.l encodingTable(a6) ; is this a double byte font?
beq.s @singleByteFont ; no, skip loading low byte
move.b highByte(a6),glyphID(a6) ; save the high byte
move.b lowByte(a6),glyphID+1(a6) ; save the low byte
@singleByteFont
endif
; 72624
MOVE.L WidthTabHandle, -(SP) ;2) Push the Width Table Handle onto the stack
PEA fontID(A6) ;1) Push the Glyph Rec Ptr
TST.B FASTFLAG(A6) ;if slow no need for 32-bit stuff
BEQ.S @skip32 ;
TST.B needs32bit(A6) ;running 32 bit clean
BEQ.S @skip32 ;NOPE, so skip it
move.b MMUsave(a6),d0 ;get previous MMU state in d0
_sbRetrieveGlyph ;Call the routine via SplineDispatch
moveq #true32b,d0 ;switch to 32 bit addressing
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
MOVE.L srcAddr(A6), A2 ;Get the address
MOVE.L A2, D0 ;get 24 bit base addr
_rTranslate24To32 ;mask off high byte
MOVE.L D0,A2 ;SAVE FOR LATER
BRA.S @skip24
@skip32
_sbRetrieveGlyph ;Call the routine via SplineDispatch
MOVE.L srcAddr(A6), A2 ;Get the address
@skip24
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Set up pointers
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.B nextBand(A6) ;another band?
BEQ.S @noBands ;no so continue
BSET.L #31, D3 ;set continue bit
BRA.S @1
@noBands
BCLR.L #31, D3 ;no new bands
@1
MOVE.L WidthTabHandle,A0 ;Get the handle
MOVE.L (A0),A4 ;restore the width table pointer
;The cacheHand may have change if we got
;Memory somewhere else
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.
MOVE.L splineKeyRec.cacheHand(A0),A0 ; Get the handle in case it changed.
MOVE.L A0, cacheHand(A6) ;restore cacheHand
MOVE.L (A0), D0 ;pointer to the cache
_StripAddress ;Make sure it is the right mode
MOVE.L D0, D5 ;restore cache pointer
MOVE.L D0, A0 ;
LEA cache.glyphArray(A0), A3 ;Get array of glyphs into A3
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.L (SP)+ ;Any Errors
MOVEM.L (SP)+, A1/D0-D2 ;Restore all registers on return
BNE @skipGlyph
MOVE.L entryOffset(A6), D0
ADD.L D0, A0 ;point to glyph record
MOVEQ #0, D0 ;No error
@skipGlyph
RTS
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END CACHE RETRIEVAL
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
renderChar
MOVEM.L D0-D1,-(SP) ;Save off all registers before JSR
MOVE.W D5, glyphID(A6) ;put glyphID into sp_Glyph
if (hasDoubleByte) then
tst.l encodingTable(a6) ; is this a double byte font?
beq.s @singleByteFont ; no, skip loading low byte
move.b highByte(a6),glyphID(a6) ; save the high byte
move.b lowByte(a6),glyphID+1(a6) ; save the low byte
@singleByteFont
endif
MOVE.W #0, topClip(A6) ;do not need the bits
MOVE.W #0, botClip(A6) ;do not need the bits
SUBQ #4,SP ;make room for result
MOVE.L WidthTabHandle, -(SP) ;2) Push the Width Table Handle onto the stack
PEA fontID(A6) ;1) Push the Glyph Rec Ptr
_sbRetrieveGlyph ;Call the routine via SplineDispatch
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Re-establish ptrs
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;The cacheHand may have change if we got
;Memory somewhere else
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.
MOVE.L splineKeyRec.cacheHand(A0),A0 ; Get the handle in case it changed.
MOVE.L A0, cacheHand(A6) ;restore cacheHand
MOVE.L (A0), A0 ;pointer to the cache
MOVE.L A0, D2 ;pointer to the cache
LEA cache.glyphArray(A0), A2 ;Get array of glyphs into A0
MOVE.L WidthTabHandle,A1 ;Get the handle
MOVE.L (A1),A1 ;restore the width table pointer
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
ADDQ #4, SP ;Ignore errors <58-CEL>
MOVEM.L (SP)+, D0-D1 ;Restore all registers on return
MOVE.L entryOffset(A6), D0
BEQ @errExit ;if zero then no info <58-CEL>
ADD.L D2, D0 ;add offset and point to glyph data
MOVE.L D0, A0 ;Get in address reg
@errExit
RTS
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END NEW FAST BLIT loop
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
ENDIF ;hasSplineFonts
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END hasSplineFontsÉ BEGIN BITMAPS
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
BitVarSetUp
MOVE stackOffset(A6),D0 ;either zero if stack was long aligned, or two if not
; MOVE.L numer(A6,D0),numer2(A6)
; MOVE.L denom(A6,D0),denom2(A6) ;save original numer, denom for iterative case
CLR charsRemain(A6) ;for iterative case
BRA.S goBitSetUp
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Iterate
;
; Entry point when subdividing a string
;
Iterate
MOVE stackOffset(A6),D0 ;either zero if stack was long aligned, or two if not
CLR -(SP) ;ROOM FOR FCN RESULT
MOVE COUNT(A6,D0),D1 ;get count
MOVE D1,-(SP) ;PUSH COUNT
BLE GOHOME ;QUIT IF COUNT <= 0
;STACK CLEANED UP BY SAVESTK
MOVE D1,countCopy(A6) ;save copy of count
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
MOVE D1,origCharCount(A6) ;save copy of count
ENDIF ;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; CALL to StdTxMeas
;
; Routine will load font and return width. StdTxMeas stashes FMOutPtr in
; QD global FONTPTR. Unscaled fixed point text width is stored in FontAdj
; for CQD not B&W.
;
MOVE.L textPtr(A6),-(SP) ;PUSH TEXTADDR
PEA NUMER(A6,D0) ;PUSH VAR NUMER
PEA DENOM(A6,D0) ;PUSH VAR DENOM
PEA INFO(A6) ;PUSH VAR INFO
lea JStdTxMeas,A0 ;get piece of trap table
move.l (a0),a0 ; <31> DTY changed from move.l
JSR (A0) ;MEASURE TEXT
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Stack Variable SetUp
;
; Registers on Entry:
; A4 = Graf globals
;
; Registers used:
; A1 = WidthPtr
; A2 = Font strike ptr
; A6 = Stack frame
; A4 = FmOutput record ptr
;
; Preserves:
; D1 = Width of string
;
; CLOBBERS: A0, D0, D2, D3
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Get the text width in D1.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
ADDQ #2,SP ;POP (and ignore) UNSCALED WIDTH RESULT
MOVE.L fontAdj(A4),D1 ;get fixed point width
MOVE.L fontPtr(A4),A4 ;Point to FmOutput record
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Common entry point for iteration or first pass. Same register setup as above, with
; the FMOutput pointer already loaded into A4. Load the font strike pointer into A2.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
goBitSetUp
CLR.L maskBitsPtr(A6) ;assume no mask
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
CLR.L stackHandle(A6) ;clear stackHandle
SF isSpline(A6) ;Set not spline font
ENDIF
MOVE.L fmOutFontH(A4),A2 ;Font Handle in register
MOVE.L (A2),A2 ;Dereference for Font Ptr
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Check font flag bits and set local flags.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
CLR.B doDither(A6) ;init to no dither <CEL-39>
MOVE stackOffset(A6),D4 ;0 if no offset, 2 if word offset
MOVE fFontType(A2),D0 ;font flags
BTST #8,D0 ;synthetic font ? <CEL-44>
SNE synFont(A6) ;used for check if orig fctb is needed <CEL-44>
BTST #9,D0 ;contains colors?
SNE colorSource(A6) ;if so, pass info to stretch later
BEQ.S @noDither ;do not set the dither bit <CEL-39>
MOVE.W numer(A6,D4),D2 ;get the numer.v <CEL-39>
CMP.W denom(A6,D4), D2 ;Check if shrinking <CEL-39>
SLT doDither(A6) ;Do the dither if shrinking <CEL-39>
@noDither ; <CEL-39>
LSR #2,D0 ;toss bottom two bits
AND #$7,D0 ;0 É 5 (bit depth of 1 É 32)
SNE D2 ;note that the incoming font is not 1 deep
MOVE D0,bitShift(A6) ;bits per pixel shift count
MOVEQ #1,D3
LSL D0,D3
MOVE D3,bitDepth(A6) ;bits per pixel
BTST #0,fFontType+1(A2) ;DOES FONT HAVE HEIGHT TABLE ?
SNE HEIGHTFLAG(A6) ;REMEMBER FOR LATER
MOVE.L numer(A6,D4),D0 ;Numer in reg <CEL-44>
CMP.L denom(A6,D4),D0 ;Is denom different <CEL-44>
SNE stretch(A6) ;Different then set the flag
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Set up the kerning properties. If this font has kerning, we only want to adjust by
; the kerning amount plus the offset for the first character in the text.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
clr.w kernBounds(a6) ; clear kerning boundary.
move.w fKernMax(a2),kernAdjust(a6) ; have a kerning adjustment?
IF hasFullKerning THEN
bpl.s @noKerning ; no -> skip kerning stuff.
move.l textPtr(a6),a0 ; load the text pointer.
clr.l d0 ; clear a long.
move.b (a0),d0 ; load the first character.
move.w fNDescent(a2),d2 ; extended offset/width table location?
bpl.s @0 ; yes -> use as the high word.
clr.l d2 ; no -> clear the high word.
@0 swap d2 ; move to the high word.
move.w LENGTH(a2),d2 ; load the low word too.
lea 16(a2,d2.l*2),a0 ; load pointer to offset/width table.
move.w 0(a0,d0.w*2),d0 ; load character offset/width.
cmp.w #-1,d0 ; missing character?
bne.s @1 ; no -> skip this.
move.w (a0),d0 ; load missing character offset/width.
@1 lsr.w #8,d0 ; isolate the offset byte.
add.w fKernMax(a2),d0 ; kerning adjustment > 0?
bgt.s @noKerning ; yes -> use kerning adjustment.
move.w d0,kernBounds(a6) ; save the kerning adjustment.
@noKerning
ENDIF
MOVE.W fDescent(A2), D0
NEG D0
MOVE.W D0, sDescent(A6) ;Descent val on stack
MOVE.W locASCENT(A2), sAscent(A6) ;Ascent val on stack
MOVE.W FBBDY(A2), sHeight(A6) ;Height val on stack
MOVE.W FBBDY(A2), TOPHT(A6) ;Top and Height vals on stack
@noItalic
MOVE txMode(A3),D0
AND #$FFF7,D0 ;clear pattern bit (let stretch reject invalid modes)
TST.B colorSource(A6) ;does the source contain colors?
BEQ.S @noColors
CMP #srcOr,D0 ;is it srcOr?
BNE.S @noColors
MOVEQ #64,D0 ;set it to srcCopy + mask
@noColors
MOVE D0,locMode(A6) ;initialize copy
BTST #6,D0 ;bit 6 if set says use a mask
SNE D3 ;remember it
BEQ.S @skipMask
LEA srcPix(A6),A0 ;assume no mask font needed; just use source instead
MOVE.L A0,maskBitsPtr(A6) ;pass mask to stretch bits
@skipMask
BTST #5,D0 ;arithmetic mode?
BEQ.S @skipArith ;if not, donÕt map if dest. is 1 bit deep
CMP #1,dstPix+pixelSize(A6) ;1 bit deep destination?
BNE.S @multideep ;if not, arithmetic mode is OK
LEA ArithMode,A0 ;get mode map
AND #7,D0 ;look at each different arith mode
MOVE.B 0(A0,D0),D0 ;map into 1 bit safe mode
MOVE D0,locMode(A6) ;alter mode properly for 1 bit depth
@skipArith
@multideep
AND.B D2,D3 ;build mask characters if incoming is not 1 deep
BEQ.S @noMask
MOVE.L widTabFont(A1),A0 ;Add offset
MOVE.L (A0),D0 ;Get pointer
SNE D3
BEQ.S @noMask
MOVE.L D0,A0 ;get address of font
MOVEQ #0,D0
MOVE fRowWords(A0),D0 ;width of strike bit map in words
ADD.L D0,D0 ;convert to bytes
MOVE.L D0,mSrcRow(A6) ;save it
LEA 26(A0),A0
MOVE.L A0,maskAddr(A6) ;address of mask bits
LEA maskBits(A6),A0 ;pointer to mask bitmap
MOVE.L A0,maskBitsPtr(A6) ;pass mask to stretch bits
@noMask
MOVE.B D3,maskFont(A6) ;0 if mask bit clear, no mask font, or incoming 1 deep
OR.B colorSource(A6),D3 ;if color source or mask font, do bit insert/extract
MOVE.B D3,textCopyMode(A6) ;set up bit insert/extract flag
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END Stack Variable SetUp
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Bounding Rect set up
;
; Setup textRect, the rectangle bounding the entire string.
;
; Registers on Entry:
; A2 = Font Ptr
; A3 = thePort
; A4 = FmOutput record ptr
; A6 = Stack frame
;
; D1 = Width of string
;
; Register Use:
; D2 = PenLocation (Set up as fixed)
;
; Clobbers:
; D0, D3
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L PNLOC(A3),D2 ;GET PEN LOCATION
MOVE.L D2,PENLOC(A6) ;SAVE FOR LATER
MOVE.W D2,TEXTRECT+LEFT(A6) ;TEXTRECT.LEFT := PNLOC.H
SWAP D2
IF hasPenFraction THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals.
move.w pnLocFixed(a0),d2 ; append pen fraction.
move.w d2,penLocFixed(a6) ; save pen fraction for recursive drawing.
ELSE
move.w #$8000,d2 ; append default fraction.
ENDIF
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; set flag to note if mode is srcOr & foreColor is black
; set up characterExtra if new port or script manager around
; set up pnLocHFrac if new port
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
CMP #srcOr,locMode(A6) ;is the mode srcOr?
SEQ orMode(A6)
BCLR #6,locMode+1(A6) ;was mask set?
BEQ.S @noMaskMode
TST locMode(A6) ;is it srcCopy + mask?
SEQ orMode(A6) ;that can go fast, too.
@noMaskMode
moveq #0, d0 ; clear the character extra. <49>
tst.b portBits+rowBytes(a3) ; is this an old grafPort?
bpl.s @oldGrafPort ; yes -> skip this.
move.w chExtra(a3),d0 ; load the character extra.
ext.l d0 ; extend sign bits <49>
asl.l #4,d0 ; convert to 16.16 format.
@oldGrafPort
IF SCRIPT_CHAR_EXTRA THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals. <43>
add.l qdChExtra(a0),d0 ; add in the character extra. <43>
ENDIF
tst.l d0 ; have zero character extra?
beq.s @zeroCharExtra ; yes -> skip call to scale.
bsr CalcCharExtra ; scale by point size, etc.
@zeroCharExtra
move.l d0,characterExtra(a6) ; store scaled character extra.
TST PORTBITS+ROWBYTES(A3) ; is it a new port?
BPL.S @useOld ; no -> donÕt set up fraction
MOVE pnLocHFrac(A3),D2 ; set up with proper fraction
MOVE D2,penLocHFrac(A6) ; save for later as well for recursive drawing
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; ForeGround - BackGround check
;
; This next part is a little tricky:
; If the source does not contain any colors (that is, regardless of whether the source is
; one bit per pixel or more, the pixels are either black or white) then we can go fast if
; the forecolor is black, regardless of the background color. If the font does contain colors,
; then we can go fast if the background is white, regardless of the foreground colors.
;
; But, if the foreground and background pixels are equal (but the font is a 1 bit font), then go
; slow. ColorMap will be called later to sort out whether the foreground color needs to be
; remapped or not.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; This is the real code
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L fgColor(A3),D0
CMP.L bkColor(A3),D0 ;same as background?
BEQ.S @goSlow ;if so, go slow
ADDQ.L #1,D0 ;now equal to number of colors, if black
MOVE dstPix+pixelSize(A6),D3 ;bits per pixel
LSR.L D3,D0 ;1 if black, 0 if other color
@goSlow
SNE D0 ;remember if black (or if fg/bk pixels are not equal)
TST.B colorSource(A6) ;is the source multicolored?
BEQ.S @oldCommon ;just worry about black
TST.L bkColor(A3) ;if colored source, must worry about bk = white also
BRA.S @oldBackCommon ;share with old mode
@useOld
BTST #5,fgColor+3(A3) ;is the foreground color black?
SNE D0 ;set to zero if not
TST.B colorSource(A6) ;is the source multicolored?
BEQ.S @oldCommon
BTST #0,bkColor+3(A3) ;is the background white?
@oldBackCommon
SEQ D0 ;true if white
@oldCommon
AND.B D0,orMode(A6) ;true if or mode and black monochrome or white multi.
ADD.L D1,D2 ;right := left + width
SWAP D2 ;just look at high word
TST.B fmOutCurStyle(A4)
BEQ noSlop ;if no style, certainly no slop
MOVEQ #0,D0 ;clear out high word
MOVE.B fmOutItalic(A4),D0 ;figure out italic
EXT.W D0 ;Make it a word
MOVE sAscent(A6),D3 ;Use the stack Ascent
SUBQ #1,D3 ;the line above the baseline is not shifted
MULU D3,D0 ;maximum italic = char ascent * FOutItalic
ASR #4,D0 ;italic factor is divided by 16 (normally 8)
@2 ADD.B fmOutBold(A4),D0 ;add boldness
SUB.B fmOutExtra(A4),D0 ;less total extra added
EXT D0 ;make it a word
MOVEQ #4,D3 ;restrict shadow in the range of 0 .. 3 (+1 if shadow)
CMP.B fmOutShadow(A4),D3 ;is it less or same?
BLE.S @pinShadow ;if so, pin at limit
MOVE.B fmOutShadow(A4),D3 ;otherwise, pass actual value
BEQ.S @pinShadow
ADDQ #1,D3 ;plus 1 for character insides shifted to right
@pinShadow
ADD D3,D0 ;combine shadow with italic slop count
ADD D0,D2 ;SLOP FOR ITALIC,BOLD,OVERSTRIKE
MOVEQ #0, D0
MOVE.B fmOutItalic(A4),D0 ;get the bit size below the baseline
MULU fDescent(A2),D0 ;maximum italic = char descent * FOutItalic
ASR #4,D0 ;which is based on 16 = 1 dot per line
IF hasFullKerning THEN
SUB D0, kernBounds(A6) ;include italic in calculating kerning
ELSE
SUB D0, kernAdjust(A6)
ENDIF
NOSLOP
IF hasFullKerning THEN
move.w kernBounds(a6),d0 ; load kerning boundary.
ELSE
move.w kernAdjust(a6),d0 ; load kerning adjustment.
ENDIF
ADD.W D0,textRect+left(A6) ;include kerning in text rectangle
MOVE.W D2,TEXTRECT+RIGHT(A6) ;STORE IN TEXTRECT.RIGHT
MOVE PENLOC(A6),D2 ;GET PNLOC.V
SUB sAscent(A6),D2 ;Use the stack Ascent
MOVE D2,TEXTRECT+TOP(A6) ;TEXTRECT.TOP := PNLOC.V - ASCENT
ADD sHeight(A6),D2 ;Height metric off stack
MOVE D2,TEXTRECT+BOTTOM(A6) ;TEXTRECT.BOTTOM := TOP + HEIGHT
MOVE.L TEXTRECT(A6),TEXTR2(A6) ;MAKE AN EXTRA COPY
MOVE.L TEXTRECT+4(A6),TEXTR2+4(A6) ;OF TEXTRECT IN TEXTR2
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Check for stretching
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.B Stretch(A6) ;Are we stretching?
BEQ NOSTRCH ;Skip stretching
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Set up for stretching
;
; We will be stretching. Setup fromRect and toRect and map textR2.
;
MOVE stackOffset(A6),D3 ;0 if no offset, 2 if word offset
MOVE.L NUMER(A6,D3),D0 ;GET NUMERATOR
SWAP D0
CLR D0 ;make it fixed point
MULU.L D0,D0:D1 ;MULT WIDTH BY NUMER.H
MOVEQ #0,D2
MOVE Denom+H(A6,D3),D2
SWAP D2
DIVU.L D2,D0:D1 ;DIV BY DENOM.H
MOVE.L PENLOC(A6),D0 ;GET PENLOC
MOVE.L D0,TORECT+TOPLEFT(A6) ;SET UP TORECT TOPLEFT
ADD.W NUMER+H(A6,D3),D0 ;CALC PENLOC.H + NUMER.H
MOVE D0,TORECT+RIGHT(A6) ;SET UP TORECT RIGHT
SWAP D0 ;GET PENLOC.V
ADD NUMER+V(A6,D3),D0 ;CALC PENLOC.V + NUMER.V
MOVE D0,TORECT+BOTTOM(A6) ;SET UP TORECT BOTTOM
MOVE.L PENLOC(A6),D0 ;GET PENLOC
MOVE.L D0,FROMRECT+TOPLEFT(A6) ;SET UP FROMRECT TOPLEFT
ADD.W DENOM+H(A6,D3),D0 ;CALC PENLOC.H + DENOM.H
MOVE D0,FROMRECT+RIGHT(A6) ;SET UP FROMRECT RIGHT
SWAP D0 ;GET PENLOC.V
ADD DENOM+V(A6,D3),D0 ;CALC PENLOC.V + DENOM.V
MOVE D0,FROMRECT+BOTTOM(A6) ;SET UP FROMRECT BOTTOM
PEA TEXTR2(A6) ;PUSH TEXTR2
PEA FROMRECT(A6) ;PUSH FROMRECT
PEA TORECT(A6) ;PUSH TORECT
_MAPRECT ;MAP TEXTR2 (PRESERVES ALL REGS)
NOSTRCH
ANDI #$0F,CCR ; need to clear 'x' flag
IF hasPenFraction THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals.
add.w d1,pnLocFixed(a0) ; add width fraction to location fraction.
ENDIF
TST PORTBITS+ROWBYTES(A3) ; is it a new port?
BPL.S @useOld ; no, donÕt bother with fraction
ADD D1,pnLocHFrac(A3)
@useOld
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Move pen by the scaled text width
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
SWAP D1 ;Make integer
MOVE PNLOC+H(A3),D0 ;Get the current pen location
ADDX D1,D0 ;New Pen Loc = OldPenLoc + TextWidth
MOVE D0,PNLOC+H(A3) ;Save new pen location
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Quit if the pen is hidden
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST PNVIS(A3) ;IS PNVIS < 0 ?
BLT GOHOME ;YES, QUIT
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END Bounding Rect set up
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Calculate the MinRect
;
; Calc minRect: the intersection of textRect, bitMap bounds,
; clipRgn and visRgn bounding boxes. Quit if no intersection.
; The right bounds of the destination rect is set to the max to allow right kerning
; (Right kerning only works (without trailing spaces) in OR mode.
;
; Registers on Entry:
; A2 = Font Ptr
; A3 = thePort
; A4 = FmOutput record ptr
; A6 = Stack frame
;
; Clobbers:
; A0, A1
; D0, D1, D2, D3
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE textR2+right(A6),-(SP) ;preserve existing right
MOVE #32000,textR2+right(A6) ;get right from other rects
PEA TEXTR2(A6) ;PUSH (MAPPED) TEXTRECT
PEA DSTPIX+BOUNDS(A6) ;PUSH PIXMAP BOUNDS
MOVE.L CLIPRGN(A3),A0 ;GET CLIPRGN HANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
PEA RGNBBOX(A0) ;PUSH CLIPRGN BBOX
MOVE.L VISRGN(A3),A0 ;GET VISRGN HANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
PEA RGNBBOX(A0) ;PUSH VISRGN BBOX
MOVE #4,-(SP) ;PUSH NRECTS=4
PEA MINRECT(A6) ;PUSH DST ADDR
_RSECT ;CALC INTERSECTION
BEQ GOHOME ;QUIT IF NO INTERSECTION
MOVE (SP)+,textR2+right(A6) ;restore text right
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Bitmap Font Ptrs SetUp
;
; Set up srcAddr, srcRow, and height
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
LEA 26(A2),a0 ;GET START OF FONT BITMAP
MOVE.L a0,SRCADDR(A6) ;SAVE FOR LATER
MOVEQ #0,D1 ;zero high word
MOVE RASTER(A2),D1 ;GET WORDS PER ROW IN FONT
MOVE bitShift(A6),D0
LSL.L D0,D1 ;scale up font rowWords
ADD.L D1,D1 ;DOUBLE FOR BYTES PER ROW
MOVE.L D1,SRCROW(A6) ;REMEMBER FOR LATER
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; FAST or NOTFAST check
;
; Test for fast case:
; not stretched, no color mapping, txMode = srcOr, same bits per pixel
; not bold, italic, underlined, outlined or shadowed,
; visRgn and clipRgn both rectangular.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.B fmOutItalic(A4) ;TEST BOLD $$$
BNE NOTFAST ;NOT FAST UNLESS BOTH ZERO
TST.B fmOutBold(A4) ;TEST BOLD
BNE NOTFAST ;NOT FAST
TST.W fmOutULThick(A4) ;Test ULTHICK and SHADOW (fmOutULThick,fmOutShadow)
BNE NOTFAST ;NOT FAST UNLESS BOTH ZERO
TST.B Stretch(A6) ;IS TEXT STRETCHED ?
BNE NOTFAST ;YES, NOT FAST
TST.B orMode(A6) ;IS TEXT MODE SRCOR ? (or srcCopy + mask, see above)
BEQ NOTFAST ;NO, NOT FAST
MOVE.L CLIPRGN(A3),A0 ; Get clip region
MOVE.L (A0),A0 ; Dereference handle
MOVEQ #10,D0
CMP RGNSIZE(A0),D0 ;IS CLIPRGN RECTANGULAR ?
BNE NOTFAST ;NO, NOT FAST
MOVEQ #1,D0
MOVE bitShift(A6),D1 ;get the depth of the source map
LSL D1,D0 ;turn into 1 ÉÊ8
CMP DSTPIX+PIXELSIZE(A6),D0 ;same depth per pixel?
BNE NOTFAST ;=>NOPE
cmp #16,dstPix+pixelType(A6) ;is it a direct device? @@@@ BAL 16Jun88
bne.s modeok
seq textCopyMode(a6) ;yes, can't go fast for now @@@@ BAL 16Jun88
clr locmode(a6) ;this essentially alters mode to srcCopy
bra NotFast
modeok
MOVE.L VISRGN(A3),A1 ;GET VISRGN HANDLE
MOVE.L (A1),A0 ;DE-REFERENCE IT
CMP #10,RGNSIZE(A0) ;IS VISRGN RECTANGULAR ?
BEQ.S FAST ;YES, TAKE FAST OPTIMIZATION
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; All systems go except for VisRgn not rectangular.
; Check if visRgn sect minRect is rectangular.
; IF TrimRect(visRgn,minRect) THEN take the fast way.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L A1,-(SP) ;PUSH VISRGN
PEA MINRECT(A6) ;PUSH MINRECT
MOVE.W #-1, -(SP) ;trim = true for BRUCE
_TRIMRECT ;CALL TRIMRECT
BLT GOHOME ;quit if intersection empty
BGT NOTFAST ;continue if non-rectangular
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END Calculate the MinRect
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; FAST case Setup
;
; Fast case, go directly to screen.
; If text is clipped vertically, then clear heightflag and update TOPHT
;
; Registers on Entry:
; A2 = Font Ptr
; A3 = thePort
; A4 = FmOutput record ptr
; A6 = Stack frame
;
; Saves & Restores:
; A2
;
; Clobbers:
;
; D0, D1
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
FAST
IF has32bitQD THEN ;If 32-bit QD was around always we could do this
MOVEM.L A0-A1/D0-D2,-(SP) ;Save registers
@tryAgain CLR.B -(SP) ;result
MOVE.L A3, -(SP) ;needs the current grafport
_QDDone ;Is accelerator really done and ready for us to blit???
TST.B (SP)+ ;Check result
BEQ.S @tryAgain ;Check until ready!
MOVEM.L (SP)+, A0-A1/D0-D2 ;Restore registers
ENDIF
@not32bit
ST FASTFLAG(A6) ;REMEMBER WE'RE GOING FAST
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Clipping set up
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
CLR.B maskFont(A6) ;no need for second mask pass in fast case
CLR.L bkCol(A6) ;zero out back color long
MOVE MINRECT+TOP(A6),D0 ;GET MINRECT.TOP
MOVE MINRECT+BOTTOM(A6),D1 ;GET MINRECT.BOTTOM
SUB TEXTRECT+TOP(A6),D0 ;was top clipped ?
BNE.S VCLIP ;yes, handle clip
CMP TEXTRECT+BOTTOM(A6),D1 ;was bottom clipped ?
BEQ.S VCLIPOK ;no, continue
VCLIP CLR.B HEIGHTFLAG(A6) ;can't use height table
MOVE.B D0,TOPHT(A6) ;use adjusted top
SUB MINRECT+TOP(A6),D1 ;calc clipped height
MOVE.B D1,TOPHT+1(A6) ;replace TOPHT
VCLIPOK MOVE TEXTRECT+TOP(A6),D0 ;GET DST TOP
SUB DSTPIX+BOUNDS+TOP(A6),D0 ;CONVERT TO GLOBAL COORDINATES
MOVE DSTPIX+ROWBYTES(A6),D1 ;GET ROWBYTES
AND #nuRBMask,D1 ;CLEAR OFF FLAG BITS
MULS D1,D0 ;MULT BY ROWBYTES
ADD.L DSTPIX+BASEADDR(A6),D0 ;ADD START OF DST BITMAP
MOVE.L D0,BUFSTART(A6) ;SET UP BUFSTART FOR LATER
MOVE D1,BUFROW(A6) ;SET UP BUFROW FOR LATER
MOVE DSTPIX+BOUNDS+LEFT(A6),BUFLEFT(A6) ;REMEMBER BUFLEFT
TST.B CRSRFLAG(A6) ;IS DST TO A SCREEN? <BAL 19Sep88>
BEQ @Check32Bit ;=>NO <9Apr90 KON>
PEA MINRECT(A6) ;PUSH SHIELD RECT
MOVE.L REALBOUNDS(A6),-(SP) ;PUSH DELTA FOR GLOBAL
_SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
@Check32Bit
tst.b needs32bit(a6) ;<9Apr90 KON>
beq.s @skip32bit ;<9Apr90 KON>
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;
; Clean pointers and then
; Switch to 32 bit addressing mode
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L SRCADDR(A6),d0 ;get 24 bit base addr
_rTranslate24To32 ;mask off high byte BAL/MCF 03Dec88
MOVE.L d0,SRCADDR(A6) ;SAVE FOR LATER
move.l a2,d0 ;get FontPtr
_rTranslate24To32 ;mask off high byte BAL/MCF 03Dec88
move.l d0,a2 ;clean font ptr
move.l a3,d0 ;get thePort ptr
_rTranslate24To32 ;mask off high byte BAL/MCF 03Dec88
move.l d0,a3 ;clean thePort ptr
MOVE.L textPtr(A6),D0 ;GET TEXTPTR
_rTranslate24To32 ;mask off high byte BAL/MCF 03Dec88
MOVE.L d0,textPtr(A6) ;SAVE FOR LATER
moveq #true32b,d0 ;switch to 32 bit addressing
move.l a2,-(sp) ;save FontPtr
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
move.l (sp)+,a2 ;restore FontPtr
move.b d0,MMUsave(a6) ;save previous state for later
@skip32bit
BRA GETPTRS
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END FAST case Setup
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Slow case Set up
;
; Slow case: Setup for an off-screen buffer.
;
; Calc bufLeft: (LONG-align to avoid shift)
;
; Registers on Entry:
; A2 = Font Ptr
; A3 = thePort
; A4 = FmOutput record ptr
; A6 = Stack frame
;
; Clobbers:
; A0, A1
; D0, D1, D2, D3, D4
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
NOTFAST
SF FASTFLAG(A6) ;NOT GOING DIRECTLY TO SCREEN
IF (hasSplineFonts AND 0) OR (Gaudi AND 0) THEN
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Horizontal buffer use that is not yet used
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.B isSpline(A6) ;Is it a spline
BEQ.S @skipNewTextRect ;Do not adjust the textrect
MOVE MINRECT+LEFT(A6), D0 ;Min left in D0
MOVE MINRECT+RIGHT(A6), D1 ;Min Right in D1
TST.B fmOutShadow(A4)
BEQ.S @noExtraOnEnds
SUB #3, D0
ADD #3, D1
@noExtraOnEnds
CMP TEXTRECT+LEFT(A6), D0 ;Is TextRect Left Greater
BLT.S @noSubLeft
MOVE D0, TEXTRECT+LEFT(A6) ;New TextRect Left used for buffer calc
@noSubLeft
CMP TEXTRECT+RIGHT(A6), D1 ;Is TextRect Left Greater
BGT.S @skipNewTextRect
MOVE D1, TEXTRECT+RIGHT(A6) ;New TextRect Right used for buffer calc
@skipNewTextRect
ENDIF
MOVE TEXTRECT+LEFT(A6),D0 ;GET TEXTRECT LEFT
SUB DSTPIX+BOUNDS+LEFT(A6),D0 ;CONVERT TO GLOBAL
AND #$FFE0,D0 ;TRUNC TO LONG BOUND
ADD DSTPIX+BOUNDS+LEFT(A6),D0 ;RETURN TO LOCAL COORDS
MOVE D0,BUFLEFT(A6) ;REMEMBER FOR LATER
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Calculate buffer size
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
CLR.L D1 ;clear high word
MOVE TEXTRECT+RIGHT(A6),D1 ;BUFRIGHT := TEXTRECT RIGHT
SUB D0,D1 ;WIDTH:=BUFRIGHT-BUFLEFT
MOVE D1,D2 ;mask depth as well
MOVE bitShift(A6),D4 ;convenient constant
LSL.L D4,D1 ;scale up by pixel size + 1 for mask
LSR.L #5,D1 ;CONVERT DOTS TO LONGS
ADD #2,D1 ;ROUND UP PLUS EXTRA LONG
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;is it a spline
BEQ.S @fullHeight ;skip bitmap clipping
MOVE.W botClip(A6), origBotClip(A6)
MOVE.W topClip(A6), origTopClip(A6)
TST.B fmOutShadow(A4)
BEQ.S @doneAdjustTop
MOVE.W botClip(A6), D3
SUB.W #2, D3
CMP.W sDescent(A6), D3
BGE.S @doneAdjustBot ;Do not adjust bottom
MOVE.W sDescent(A6), D3
@doneAdjustBot
MOVE.W D3, botClip(A6)
MOVE.W topClip(A6), D3
ADD.W #3, D3
CMP.W sAscent(A6), D3
BGE.S @setTopSame ;Do not adjust bottom
MOVE.W D3, topClip(A6)
BRA.S @doneAdjustTop
@setTopSame
MOVE.W sAscent(A6), topClip(A6)
@doneAdjustTop
MOVE.W topClip(A6), D3 ;Get the top clipping height
MOVE.W D3, topAdjust(A6) ;Get top adjust for dest adjustment
SUB.W botClip(A6), D3 ;Not missing but really clipped out
BLE.W GOHOME ;Done if zero
ADD.W #1, D3 ;height = topClip - botClip + 1
MOVE.W D3, bufHeight(A6) ;Save it away
BRA.S @skipFullHeight ;Do not get full height for buffer
ENDIF ;$$$NEW
@fullHeight
MOVE sHeight(A6),D3 ;GET HEIGHT
@skipFullHeight
MULU D1,D3 ;BUFSIZE:=HEIGHT*BUFROW LONGS
IF 0 THEN
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;skip check if spline
BNE.S @noCompare ;Do not compare
ENDIF
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; if the intermediate result is too big, stop before going any further
;
; Why does this happen???
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
CMP.L #$1C00,D3 ;is it bigger than 28K? (unit is longs)
BGT DoSubDivide ;if so, draw fewer characters at a time
@noCompare
ENDIF
MOVE.L D3,BUFSIZE(A6) ;Made a long SAVE FOR LATER
EXT.L D1 ;Make it a long
ADD.L D1,D3 ;add for stretch srcBuf
LSL #2,D1 ;QUAD BUFROW FOR BYTES
MOVE D1,BUFROW(A6) ;SAVE FOR LATER
MOVE TEXTR2+RIGHT(A6),D5
SUB TEXTR2+LEFT(A6),D5
LSR #5,D5 ;convert to longs
ADDQ #2,D5 ;account for slop
MOVE D5,D0
EXT.L D0 ;Make it a long
ADD.L D0,D3 ;in case clip is nonrectangular
ADD.L D0,D3 ;in case vis is nonrectangular
LSL D4,D0 ;scale up by source depth
ADD.L D0,D3 ;add stretch destination buffer size
MULU dstPix+pixelSize(A6),D5 ;size of composite mask
EXT.L D5 ;$$$ Make it a long
ADD.L D5,D3 ;include it
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;if srcDepth not equal to dstDepth, add stretch dest. buf. again
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
ADD.L D5,D3 ;include space for scale buffer
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;set up maskSize, maskRow
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.B maskFont(A6) ;do we need a mask to pass to stretchBits?
BEQ.S @noMask
LSR #5,D2 ;CONVERT DOTS TO LONGS
ADD #2,D2 ;ROUND UP PLUS EXTRA LONG
ADD D2,D1 ;total number of longs
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;is it a spline
BEQ.S @useNormalHeight ;use the normal height
MOVE bufHeight(A6), D0 ;use bufHeight
BRA.S @contCalc
@useNormalHeight
MOVE sHeight(A6),D0 ;GET HEIGHT
@contCalc
ELSE
MOVE sHeight(A6),D0 ;GET HEIGHT
ENDIF
MULU D2,D0 ;BUFSIZE:=HEIGHT*BUFROW LONGS
MOVE D0,maskSize(A6) ;SAVE FOR LATER
LSL #2,D2 ;QUAD BUFROW FOR BYTES
MOVE D2,mBufRow(A6) ;SAVE FOR LATER
ADD.L D0,D3 ;add for stack check calculation
EXT.L D2
ADD.L D2,D3 ;add for stretch srcMaskBuf
MOVE TEXTR2+RIGHT(A6),D0
SUB TEXTR2+LEFT(A6),D0
LSR #5,D0 ;convert from dots to longs
EXT.L D0 ;Make it a long
ADD.L D0,D3 ;add stretch mask destination buffer size
@noMask
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;Is it a spline
BNE.S @doNewAlloc ;Then subdivide
ENDIF
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Calculate total stack requirements for off-screen buffers.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.B fmOutShadow(A4) ;ARE WE SHADOWING ?
BEQ.S @1 ;NO, CONTINUE
ADD.L bufSize(A6),D3 ;(long) YES, CALC 2*BUFSIZE
EXT.L D1 ;make long for long add
ADD.L D1,D3 ;add in 4 * source rows for shadow
@1 LSL.L #2,D3 ;CALC TOTAL STACK BYTES NEEDED
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; how much slop? size of scale table (256 bytes maximum)
; size of stretch stack frame (750 bytes for parameters, local stack frame, saved regs),
; and about 1K for interrupts.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
ADD.L #2048,D3 ;ADD 2 KBYTE SLOP
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; If stack is too small to allocate buffer(s), then draw half as many characters at a time.
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
_StackAvail ;Get StackAvail IN D0
CMP.L D0,D3 ;IS stackNeeded > stackAvail ?
BLE StackAlmost ;NO, CONTINUE
BRA DoSubDivide
@doNewAlloc
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Calculate the buffer size
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L bufSize(A6),D0 ;Get size of buffer to initialize
ADD.L #2, D0 ;Add 2 padding buffer on each end
TST.B maskFont(A6)
BEQ.S @skipMaskAlloc
MOVEQ #0, D1 ;clear the long
MOVE maskSize(A6),D1 ;Get maskSize
ADD.L D1,D0 ;Adding in maskSize
ADD.L #2, D0 ;Add 2 padding buffer on each end
@skipMaskAlloc
TST.B fmOutShadow(A4) ;Is there shadow
BEQ.S @noShadBuf ;SKIP IF NO SHADOWING
ADD.L bufSize(A6),D0 ;GET NUMBER OF LONGS IN BUF1
MOVE BUFROW(A6),D1 ;GET 4 * NUMBER OF LONGS PER ROW
EXT.L D1
ADD.L D1,D0 ;GET 4 * NUMBER OF LONGS PER ROW
ADD.L #2, D0 ;Add 2 padding buffer on each end
@noShadBuf
LSL.L #2, D0 ;longs to bytes
MOVE.L D0, D3 ;Save value away
CMP.L #$7000,D3 ;is it bigger than 28K? (unit is longs)
BGT.S @otherAlloc ;Try to get memory from other places
_StackAvail ;Get StackAvail IN D0
MOVE.L D3, D2 ;get needed space
ADD.L #3346, D2 ;make sure there is an extra 2.5k bytes
CMP.L D0,D2 ;IS stackNeeded > stackAvail ?
BGT.S @otherAlloc ;NEW Changed to word branch - NO, CONTINUE
SUB.L D3, SP ;Allocate the sucker
MOVE.L SP, bufferPtr(A6) ;Save away the buffer pointer
BRA @gotIt ;<65-CEL>
@otherAlloc
MOVE.L fmOutFontH(A4),A0 ;GET FONT HANDLE
_HGetState ;get the purge state
MOVE.B D0,fontState(A6) ;preserve it until the next change
_HNoPurge ;Make it non-purgeable
MOVE.L cacheHand(A6),A0 ;GET cache HANDLE <65-CEL>
_HGetState ;get the purge state <65-CEL>
MOVE.B D0,cacheState(A6) ;preserve it until the next change <65-CEL>
_HNoPurge ;Make it non-purgeable <65-CEL>
MOVE.L stackHandle(A6), D0 ;Check if exists
BEQ.S @skipReSize
MOVE.L D0, A0 ;Get handle in A0
_HUnlock
MOVE.L D3, D0 ;restore size
_SetHandleSize ;try a sethandlesize first
BEQ.S @gotMem ;No problems we got it
_DisposHandle ;Get rid of buffer - could be MF temp handle
CLR.L stackHandle(A6) ;Zero out handle
@skipReSize
MOVE.L D3, D0 ;restore size
MOVE.L A4,-(SP) ;save a4 <PN>
BigJSR GetStyleBufHand,A4 ;Expecting size in D0 <PN>
MOVE.L (SP)+,A4 ;restore a4 <PN>
BEQ.S @subDivide ;go and band
MOVE.L A0, stackHandle(A6) ;save away for later
@gotMem
MOVEM.L A0-A1/D0-D2,-(SP) ;Save off all registers before JSR
SUBQ #4,SP ;make room for result
MOVE.L widthTabHandle,A0 ;point to width table
MOVE.L A0, -(SP) ;Push the WidthTable
MOVE.L (A0),A0 ;Ptr to widthtable
MOVE.L WidTabFont(A0), -(SP) ;font handle
MOVE.W bufHeight(A6), -(SP) ;Scan lines
MOVE.W WidthASize(A0), -(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
BNE.S @subDivide ;
_MoveHHi ;Move it high
_HLock ;Lock it down for now
MOVE.L (A0), D0 ;pointer to the cache
_StripAddress ;Make sure it is the right mode
MOVE.L D0, bufferPtr(A6) ;Save away the buffer pointer
MOVE.L fmOutFontH(A4),A0 ;GET FONT HANDLE
MOVE.B fontState(A6), D0 ;preserve it until the next change
_HSetState ;restore purgability of original strike
MOVE.L cacheHand(A6),A0 ;GET FONT HANDLE <65-CEL>
MOVE.B cacheState(A6), D0 ;preserve it until the next change <65-CEL>
_HSetState ;restore purgability of original strike <65-CEL>
@gotIt BRA StackAlmost ; We are in business
@subDivide
MOVE.L fmOutFontH(A4),A0 ;GET FONT HANDLE
MOVE.B fontState(A6), D0 ;preserve it until the next change
_HSetState ;restore purgability of original strike
ENDIF
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; SUB-dividing routine
;
; Not enough memory - Divide area
;
; Currently there are two types of sub-dividing.
; 1) splitting the string in half
; 2) Banding vertically
;
; Banding vertically will render the characters correctly for all styles
; It seems as though splitting the string could have bad effects in italics
; in certain modes (e.g., srccopy). The sub-dividing of strings may go away
; In the case for splines, banding vertically will only take place. Splitting
; the string may also run out of memory and still need to be banded vertically.
; Banding vertically seems to be the best approach. Note: By banding vertically
; StdTxmeas will not need to be called again. The setup does not need to be re-done
;
; Registers on Entry:
; A2 = Font Ptr
; A3 = thePort
; A4 = FmOutput record ptr
; A6 = Stack frame
;
; Clobbers:
; A0, A1
; D0, D3, D6, D7
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
DoSubDivide
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;is it a spline
BEQ.S @contNormSplit ;skip bitmap clipping
ST clipVert(A6) ;banding so set clip vertical flag <51>
MOVE.W origTopClip(A6), D3 ;Get original value
SUB.W origBotClip(A6), D3 ;Get original height to divide
LSR.W #1, D3 ;Divide by 2 is new Height
MOVE.W origBotClip(A6), -(SP) ;nextBotClip = botClip
MOVE.W origTopClip(A6), D0 ;Get topclip
SUB.W D3, D0 ;Get new botClip
MOVE.W D0, -(SP) ;nextTopClip = newBotClip-1
MOVE.W D0, botClip(A6) ;newBotClip = (topClip - (oldHeight / 2)) + 1
@noNew
MOVE.L SP, clipStorage(A6) ;Save Address on variable for later cleanup
ADD.W #1, repeatBands(A6) ;Bump up by one
MOVE.B HiliteMode,saveHilite(A6) ;save original in case stretch is called multiple times
MOVE.L PENLOC(A6),PNLOC(A3) ;RESTORE PNLOC TO ORIGINAL
IF hasPenFraction THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals.
move.w penLocFixed(a6),pnLocFixed(a0) ; restore fractional pen location.
ENDIF
TST PORTBITS+ROWBYTES(A3) ; is it a new port?
BPL.S @useOld2 ; no, no fraction to restore
MOVE PenLocHFrac(A6),pnLocHFrac(A3) ;restore fraction if applicable
@useOld2
BRA NOTFAST ;do new divide
@contNormSplit
ENDIF
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Here is the bitmap subdivide of the string
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE stackOffset(A6),D6 ;2 if stack was not aligned, otherwise, 0
MOVE count(A6,D6),D0 ;how many characters to draw
MOVE.W D0,D7 ;figure half
LSR #1,D7
BNE.S @subDivide ;if more than 1 left, can subdivide problem
SUBQ #1,charsRemain(A6) ;pretend the one character was drawn
BRA GoHome ;if only 1 character, punt
@subDivide
; *** look for space character? Could adjust D7 to coincide with a space if any, making
; *** drawing look better (for italics, kerns)
TST charsRemain(A6) ;if zero, this is the first time through
BNE.S @notFirst
MOVE.B HiliteMode,saveHilite(A6) ;save original in case stretch is called multiple times
MOVE D0,charsRemain(A6) ;initialize partial count drawing location
@notFirst
MOVE.L PENLOC(A6),PNLOC(A3) ;RESTORE PNLOC TO ORIGINAL
IF hasPenFraction THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals.
move.w penLocFixed(a6),pnLocFixed(a0) ; restore fractional pen location.
ENDIF
TST PORTBITS+ROWBYTES(A3) ; is it a new port?
BPL.S @useOld ; no, no fraction to restore
MOVE PenLocHFrac(A6),pnLocHFrac(A3) ;restore fraction if applicable
@useOld
MOVE D7,count(A6,D6) ;reset count to draw
doIterate
MOVE.L grafGlobals(A5),A4 ;set up grafGlobals pointer for getting real width
MOVE.L numer2(A6),numer(A6,D6) ;restore numerator
MOVE.L denom2(A6),denom(A6,D6) ;restore denominator
MOVE.B saveHilite(A6),HiliteMode ;restore hilite bit
JMP Iterate ;draw first half of string
; draw the second half of the string, but drawing no more characters than could be successfully
; drawn by the first half.
secondHalf
MOVEQ #0,D7 ;zero high word
MOVE stackOffset(A6),D6 ;2 if stack was not aligned, otherwise, 0
MOVE count(A6,D6),D7 ;number of characters drawn last
MOVE charsRemain(A6),D0 ;how many characters remain?
CMP D0,D7 ;donÕt try to draw more than worked last
BLE.S @ok
MOVE D0,count(A6,D6) ;draw what remains for the second half
@ok
ADD.L D7,textPtr(A6) ;bump source address by half already drawn
BRA.S doIterate
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END SUB-dividing routine
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Off-Screen Allocation
;
; Allocate and clear an off-screen buffer
;
; If the source font is only 1 bit deep, clear the screen to white. Also, if the transfer
; mode is xor, bic, or, clear the screen to white. If an arithmetic mode or copy and
; source is multibits deep, assume depth of source font is equal to destination depth.
; Also assume that background of buffer must be colored the same as the port background color.
;
;
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
StackAlmost
MOVEQ #0,D0 ;get a long of white
CMP.W #16, destDepth(A6) ;get destination bits per pixel
BGE.S @whiteBackCol ;16 or 32 bit will not happen
TST bitShift(A6) ;is source 1 bit?
BEQ.S @whiteBackCol ;
CMP #srcXor,locMode(A6) ;srcXor?
BEQ.S @whiteBackCol ;even if font contains colors, leave background white
TST.B colorSource(A6) ;font contains color?
BNE.S @useBackCol ;if so, must color the buffer
CMP #$32,locMode(A6) ;hilite?
BEQ.S @whiteBackCol ;leave background white if so
BTST #5,locMode+1(A6) ;arithmetic?
BEQ.S @whiteBackCol ;if copy, or leave background white
@useBackCol
SUBQ #6,SP ;allocate VAR RGBColor
MOVE.L SP,-(SP) ;point to VAR RGBColor
_GetBackColor ;ask for the background color
CLR.L -(SP) ;make room for function result
PEA 4(SP) ;point to VAR RGBColor
_Color2Index
MOVEQ #0,D0
MOVEQ #32,D1 ;
MOVE bitDepth(A6),D2 ;get destination bits per pixel
@nxtPixel
ASL.L D2,D0
OR.l (SP),D0 ;or in result of color2Index <BAL 04July88>
SUB D2,D1
BGT.S @nxtPixel
ADD #10,SP ;strip RGBColor and long result
@whiteBackCol
MOVE.L D0,bkCol(A6) ;save for comparing with background, later
STACKOK
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6)
BEQ.S oldAlloc ;Go to old way of allocating
MOVE.L bufferPtr(A6), A0 ;Point to the buffer
MOVE.L D0,(A0)+ ;PAD BUFFER WITH AN EXTRA ZERO
MOVE.L A0, BUFSTART(A6) ;Save the start of the buffer
MOVE.L bufSize(A6),D3 ;Get size of buffer to initialize
SUBQ #1,D3 ;INIT DBRA LOOP COUNT
CLRLP MOVE.L D0,(A0)+
SUB.L #1, D3 ;Decrement count
TST.L D3 ;Is it done looping
BGT.S CLRLP ;Done looping
MOVE.L A0, bufEnd(A6) ;point to end of buffer
MOVE.L D0,(A0)+ ;PAD BUFFER WITH AN EXTRA ZERO
TST.B maskFont(A6)
BEQ.S @noMask
CLR.L (A0)+
MOVE.L A0, maskStart(A6) ;Set the maskStart pointer
MOVE maskSize(A6),D3 ;Get the size of the mask
SUB #1, D3 ;Init loop count
@clrMask
CLR.L (A0)+
DBRA D3,@clrMask
@noMask
MOVE.L A0, currentEnd(A6) ;current end of allocated buffer
BRA.S doneNEW1
oldAlloc
MOVE.L bufSize(A6),D3
SUBQ #1,D3 ;INIT DBRA LOOP COUNT
MOVE.L D0,-(SP) ;PAD BUFFER WITH AN EXTRA ZERO
MOVE.L SP,BUFEND(A6) ;REMEMBER WHERE BUFFER ENDS
CLRLOOP MOVE.L D0,-(SP)
DBRA D3,CLRLOOP ;ALLOCATE AND CLEAR BUFFER
MOVE.L SP,BUFSTART(A6) ;REMEMBER START OF BUFFER
MOVE.L D0,-(SP) ;PAD BUFFER WITH AN EXTRA ZERO
TST.B maskFont(A6)
BEQ.S @noMask
MOVE maskSize(A6),D3
SUBQ #1,D3
CLR.L -(SP)
@clrMask
CLR.L -(SP)
DBRA D3,@clrMask
MOVE.L SP,maskStart(A6)
@noMask
CLR.L -(SP)
doneNEW1
ELSE
MOVE.L bufSize(A6),D3
SUBQ #1,D3 ;INIT DBRA LOOP COUNT
MOVE.L D0,-(SP) ;PAD BUFFER WITH AN EXTRA ZERO
MOVE.L SP,BUFEND(A6) ;REMEMBER WHERE BUFFER ENDS
CLRLOOP MOVE.L D0,-(SP)
DBRA D3,CLRLOOP ;ALLOCATE AND CLEAR BUFFER
MOVE.L SP,BUFSTART(A6) ;REMEMBER START OF BUFFER
MOVE.L D0,-(SP) ;PAD BUFFER WITH AN EXTRA ZERO
TST.B maskFont(A6)
BEQ.S @noMask
MOVE maskSize(A6),D3
SUBQ #1,D3
CLR.L -(SP)
@clrMask
CLR.L -(SP)
DBRA D3,@clrMask
MOVE.L SP,maskStart(A6)
@noMask
CLR.L -(SP)
ENDIF
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;Is it a spline
BEQ.S @1 ;no so continue to bitmap getptrs
TST.W clipVert(A6) ;Horz or Vert clipped
BNE sGetPtrs ;take clipping loops
BRA FastBlit ;go really fast
@1
ENDIF
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END Off-Screen Allocation
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END Slow case Set up
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;
; Get pointers to location table, width table, and height table in font
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
GETPTRS
LEA 26(A2),A0 ;GET START OF FONT BITMAP
MOVEQ #0,D0 ;zero high word
MOVE sHeight(A6),D0 ;GET HEIGHT OF FONT BITMAP
MOVE.L SRCROW(A6), D1 ;Get Source in D1 to use as word, never a long
MULU.W D1,D0 ;CALC TOTAL SIZE OF STRIKE
ADD.L D0,A0 ;A1 := START OF LOC TABLE
MOVE.L A0,LOCTAB(A6) ;SAVE FOR LATER
MOVE.W fNDescent(A2),D0 ;possibly the high word of owTLoc
SWAP D0 ;put it in the high word
BPL.S @notNegative
MOVEQ #0,D0 ;old fonts have negative of ascent here
@notNegative
MOVE LENGTH(A2),D0 ;HOW MANY WORDS IN STRIKE BODY
LEA 16(A2,D0.L*2),A1 ;GET START OF WIDTH TABLE
MOVE.L A1,WIDTAB(A6) ;SAVE FOR LATER
MOVE MAXCHAR(A2),D0 ;GET MAXCHAR
MOVE MINCHAR(A2),D1 ;GET MINCHAR
MOVE D1,MINCH(A6) ;STASH MINCHAR FOR LATER
SUB D1,D0 ;CALC MAXCHAR-MINCHAR
MOVE D0,MAXMIN(A6) ;SAVE FOR LATER
ADD #3,D0 ;CALC MAXMIN+3
BTST #1,1(A2) ;DOES FONT HAVE WIDTH TABLE ?
BEQ.S NOWID ;NO, CONTINUE
ADD D0,D0 ;SKIP WIDTH TABLE
NOWID
LEA 0(A1,D0*2),A0 ;POINT TO HEIGHT TABLE
MOVE.L A0,HEIGHTAB(A6) ;SAVE FOR LATER
skipBitTables ;Skipped the bitmap table setup
;
; Set up space width
;
MOVE.L widthTabHandle,A0 ;point to width table
MOVE.L (A0),A0
MOVE.L A0, widTabPtr(A6) ;Save pointer to the width table
MOVE.L 128(A0),SPWIDTH(A6) ;get width of the space char
;
; Setup misc stuff in registers for speed
;
MOVE BUFLEFT(A6),D1 ;GET BUFLEFT
MOVE PENLOC+H(A6),D0 ;GET PEN LOCATION
ADD kernAdjust(A6),D0 ;ADJUST FOR KERNING
SUB D1,D0 ;MAKE CHARLOC RELATIVE TO BUFLEFT
MOVE.W D0,CHARLOC(A6) ;LOAD INTEGER PART
IF hasPenFraction THEN
move.w penLocFixed(a6),charLoc+2(a6) ; use saved fraction.
ELSE
move.w #$8000,charLoc+2(a6) ; default fraction to 1/2.
ENDIF
TST PORTBITS+ROWBYTES(A3) ; is it a new port?
BPL.S @useOld ; no -> skip this.
MOVE penLocHFrac(A6),CHARLOC+2(A6) ; use saved fraction.
@useOld
SUB D1,MINRECT+LEFT(A6) ;MAKE MINRECT.LEFT AND
SUB D1,MINRECT+RIGHT(A6) ;MINRECT.RIGHT BUFFER RELATIVE
MOVE.L textPtr(A6),A1 ;GET TEXTPTR
BRA.S NEXTCH ;GO TO LOOP START
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;
; Here's the main character drawing loop:
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MISSING
MOVE MAXMIN(A6),D5 ;NO, USE MISSING SYMBOL
ADD #1,D5 ;WHICH IS ONE PAST MAXCHAR
MOVE.L WIDTAB(A6),A0 ;POINT TO WIDTH TABLE
MOVE 0(A0,D5*2),D3 ;GET OFFSET AND WIDTH BYTES
CMP #-1,D3 ;missing?
BNE NOTMISS ;IS MISSING CHAR MISSING ?
BRA.S NEXTCH ;YES, SKIP THIS CHAR
SPACECH MOVE.L SPWIDTH(A6),D1 ;GET SPACE WIDTH
ADD.L D1,CHARLOC(A6) ;BUMP CHARLOC
SKIPCH SUBQ.W #1,charsRemain(A6) ;decrement total character count
SUBQ.W #1,countCopy(A6) ;decrement partial draw character count
BLE STRDONE ;QUIT IF CHARCOUNT <= 0
NEXTCH MOVEQ #0, D5 ;get ready for byte
MOVE.B (A1)+,D5 ;GET NEXT CHAR
CMP.B #32,D5 ;IS IT A SPACE ?
BEQ.S SPACECH ;YES, HANDLE IT
MOVE.L widTabPtr(A6),A0 ;Point to the width table
MOVE.L 0(A0,D5*4),D4 ;GET FIXED POINT WIDTH
ADD.L characterExtra(A6),D4 ;add in character extra, if any
SUB MINCH(A6),D5 ;SUBTRACT SAVED MINCHAR
CMP MAXMIN(A6),D5 ;IS CH BETWEEN MINCHAR AND MAXCHAR ?
BHI MISSING ;Missing so skip it
OKCHAR MOVE.L WIDTAB(A6),A0 ;POINT TO WIDTH TABLE
MOVE 0(A0,D5*2),D3 ;GET OFFSET AND WIDTH BYTES
CMP #-1,D3 ;missing?
BEQ MISSING ;OFFSET NEG = MISSING CHAR
NOTMISS LSR #8,D3 ;GET OFFSET BYTE
ADD.W CHARLOC(A6),D3 ;DSTLEFT := CHARLOC.INT + OFFSET
ADD.L D4,CHARLOC(A6) ;ADD FIXED POINT WIDTH TO CHARLOC
MOVE.L LOCTAB(A6),A0 ;POINT TO LOCATION TABLE
MOVEQ #0,D1 ; *** clear top word
MOVE 0(A0,D5*2),D1 ;GET SRCLEFT
MOVE 2(A0,D5*2),D2 ;GET SRCRIGHT
SUB D1,D2 ;CALC WIDTH OF BITS
BLE SKIPCH ;SKIP CHARBLT IF WIDTH <= 0
MOVE D2,charWidth(A6) ;save for later
ADD D3,D2 ;DSTRIGHT := DSTLEFT + WIDTH
TST.B HEIGHTFLAG(A6) ;does font have height table ?
BEQ.S NOHEIGHT ;no, continue
MOVE.L HEIGHTAB(A6),A0 ;get height table
MOVE 0(A0,D5*2),TOPHT(A6) ;get this char's top and height
NOHEIGHT
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Horizontal Clipping
;
; Horizontal clip only if FastFlag: (else stretch,outline,shadow,italic die)
;
; skip if hidden on left, string done if hidden on right.
;
; at this point: D1: srcLeft
; D2: dstRight
; D3: dstLeft
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.B FastFlag(A6) ;ARE WE GOING FAST ?
BEQ.S HORIZOK ;NO, DON'T CLIP
CMP MINRECT+LEFT(A6),D3 ;IS DSTLEFT < MINRECT.LEFT ?
BGE.S LEFTOK ;NO, CONTINUE
CMP MINRECT+LEFT(A6),D2 ;IS DSTRIGHT <= MINRECT.LEFT ?
BLE SKIPCH ;YES, SKIP THIS CHAR
TRIMLFT MOVE MINRECT+LEFT(A6),D0 ;NO, GET MINRECT.LEFT
SUB D3,D0 ;DISCARD:=MINRECT.LEFT-DSTLEFT
ADD D0,D1 ;SRCLEFT:=SRCLEFT+DISCARD
ADD D0,D3 ;DSTLEFT:=DSTLEFT+DISCARD
CMP MINRECT+RIGHT(A6),D2 ;IS DSTRIGHT > MINRECT.RIGHT ?
BLE.S fixCharWidth ;NO, CONTINUE
BRA.S TRIMRT ;YES, TRIM RIGHT
LEFTOK CMP MINRECT+RIGHT(A6),D2 ;IS DSTRIGHT <= MINRECT.RIGHT ?
BLE.S HORIZOK ;YES, CONTINUE
CMP MINRECT+RIGHT(A6),D3 ;IS DSTLEFT >= MINRECT.RIGHT ?
BGE STRDONE ;YES, IGNORE REST OF STRING
TRIMRT MOVE MINRECT+RIGHT(A6),D2 ;NO, TRIM DSTRIGHT
fixCharWidth
MOVE D2,D0 ;char width has been trimmed left, right, or both
SUB D3,D0 ;so recalculate char width to draw
MOVE D0,charWidth(A6) ;and save this tidbit of info. for later
HORIZOK
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Blit loop for the 68020+ machines
;
; Inputs to local block CharBlt:
;
; srcAddr(A6)
; srcRow(A6)
; bufStart(A6) = dstAddr
; bufRow(A6) = dstRow
; D1 = srcLeft
; D2 = dstRight relative to buffer, > dstLeft
; D3 = dstLeft relative to buffer
; TOPHT(A6) top and height
;
; CLOBBERS: D0,D1,D2,D3,D4,D5,D6,D7,A0,A2,A3,A4,A5
; PRESERVES: A1,A6,A7
;
;
; Setup shift count in D5 (relative shift between src and dst)
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVEM D1-D3,maskBlts(A6)
MOVE.B textCopyMode(A6),orNotOK(A6) ;if copy or if mask mode, do bit moves instead of OR
ST notMaskPass(A6) ;use the bitDepth this pass
MOVE BUFROW(A6),A3
MOVEM.L SRCROW(A6),A2/A4-A5 ;srcRow, srcAddr (src bitmap), bufStart (dst bitmap) <1.4-4april89-CEL>
MOVE bitShift(A6),D0 ;get font scale factor
LSL D0,D1
LSL D0,D2
LSL D0,D3 ;scale up all three
maskBlt
;
; Get char height into D7
;
MOVE.W #255,D7 ;GET -1 BYTE, CLEAR HI BYTE
ADD.B TOPHT+1(A6),D7 ;CALC HEIGHT-1 FOR DBRA LOOP
BMI SKIPCH ;OOPS HEIGHT WAS ZERO !
;
; Adjust srcPtr and dstPtr for charTop
;
MOVEQ #0,D0 ;get ready for byte
MOVE.B TOPHT(A6),D0 ;get char top
MOVE.L A2,D4 ;get srcRow in D-reg
MULU.L D0,D4 ;calc charTop * srcRow
ADD.L D4,A4 ;add to srcPtr
MOVE A3,D4 ;get dstRow in D-reg
MULU D0,D4 ;calc charTop * dstRow
ADD.L D4,A5 ;add to dstPtr
BRA pastBitMapPointers
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;
; SPLINE DRAWING LOOP
;
; Registers Use:
; D0 = xxxxxxx A0 = xxxxxxx
; D1 = xxxxxxx A1 = TextPtr
; D2 = xxxxxxx A2 = xxxxxxx
; D3 = xxxxxxx A3 = xxxxxxx
; D4 = Advance Width A4 = xxxxxxx
; D5 = Char Code A5 = xxxxxxx
; D6 = xxxxxxx A6 = stack frame
; D7 = xxxxxxx A7 = xxxxxxx
;
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
sGETPTRS
MOVE stackOffset(A6),D0
MOVE.L textPtr(A6),A1 ;GET TEXTPTR
MOVE.L cacheHand(A6), A0 ;Handle to the cache
MOVE.L (A0), D0 ;pointer to the cache
_StripAddress ;Make sure it is the right mode
MOVE.L D0, cachePtr(A6) ;save it for later
MOVE.L D0, A0
LEA cache.glyphArray(A0), A0 ;Get array of glyphs into A0
MOVE.L A0, glyphArray(A6) ;Save the glyph array pointer
;
; Set up space width
;
MOVE.L widthTabHandle,A0 ;point to width table
MOVE.L (A0),A0
MOVE.L A0, widTabPtr(A6) ;Save pointer to the width table
; MOVE.L 128(A0),SPWIDTH(A6) ;get width of the space char
; Setup misc stuff in registers for speed
;
MOVE BUFLEFT(A6),D1 ;GET BUFLEFT
MOVE PENLOC+H(A6),D0 ;GET PEN LOCATION
SUB D1,D0 ;MAKE CHARLOC RELATIVE TO BUFLEFT
MOVE.W D0,CHARLOC(A6) ;INIT INT PART OF CHARLOC
TST PORTBITS+ROWBYTES(A3) ;is it a new port?
BPL.S @useOld ;no, set fraction to 1/2
MOVE penLocHFrac(A6),CHARLOC+2(A6) ;set up fractional part <PB362> BAL
BRA.S @goOn
@useOld
MOVE #$8000,CHARLOC+2(A6)
@goOn
SUB D1,MINRECT+LEFT(A6) ;MAKE MINRECT.LEFT AND
SUB D1,MINRECT+RIGHT(A6) ;MINRECT.RIGHT BUFFER RELATIVE
BRA.S sNextCh ;Start first character
sNextBand
MOVE.W glyphID(A6), D5 ;put glyphID into d5 for renderIt
BRA doBand ;take care of the band
sMiss
IF HAS_COLOR | SCRIPT_CHAR_EXTRA THEN ;<7> CEL
CMP.B #32,D5 ;IS IT A SPACE ?
BEQ.S sSPACECH ;YES, HANDLE IT
ADD.L characterExtra(A6),D4 ;add in character extra, if any
sSPACECH
ENDIF
ADD.L D4, CHARLOC(A6) ;Add fixed point width to CharLoc
sSKIPCH SUBQ.W #1,countCopy(A6) ;decrement partial draw character count
BLE STRDONE ;QUIT IF CHARCOUNT <= 0
sNextCh
TST.B nextBand(A6) ;another char band then call retrieve!!!
BNE.S sNextBand ;do the next char band
MOVEQ #0, D5 ;get ready for byte
MOVE.B (A1)+,D5 ;GET NEXT CHAR
if (hasDoubleByte) then
move.b d5,highByte(a6) ; save the high byte for later use
clr.b lowByte(a6) ; clear the low byte for now
tst.l encodingTable(a6) ; is this a double byte font?
beq.s @normalFont ; no, skip low byte loading
move.l encodingTable(a6),a0 ; grab pointer to high byte mapping table
tst.b 0(a0,d5.w) ; is this a double byte character?
beq @normalCharacter ; no, skip low byte loading
tst.w countCopy(a6) ; more bytes left in text?
ble.s @remapCharacterToNull ; no, remap the high byte
subq.w #1,countCopy(a6) ; decrement the character count
clr.w d0 ; clear high byte of low word
move.b (a1)+,d0 ; grab the low byte and bump the text pointer
adda.w #256,a0 ; offset to the low byte encoding table
tst.b 0(a0,d0.w) ; is this a valid low byte?
beq @remapCharacterToNull ; no, remap the high byte character
move.b d0,lowByte(a6) ; save the valid low byte for later use
bra @normalCharacter ; continue normally
@remapCharacterToNull
move.b #1,d5 ; remap the high byte character to the missing glyph
move.b d5,highByte(a6) ; save the remapped value in the stack
@normalCharacter
@normalFont
endif
MOVE.L widTabPtr(A6),A0 ;Point to the width table
MOVE.L 0(A0,D5*4),D4 ;GET FIXED POINT WIDTH
MOVE.L glyphArray(A6), A0 ;Get array of glyphs into A0
MOVE.L 0(A0,D5*4),D0 ;Get offset to glyph in D3
BGT isCached
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; calling _sbRetrieveGlyph
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
errorOrNotCached
BTST.L #30, D0 ;Check if there is an error
BNE.S sMiss ;Got an error so skip character
doBand
MOVEM.L A1/D2,-(SP) ;Save off all registers before JSR
SUBQ #4,SP ;make room for result
MOVE D5, glyphID(A6) ;put glyphID into sp_Glyph
if (hasDoubleByte) then
tst.l encodingTable(a6) ; is this a double byte font?
beq.s @singleByteFont ; no, skip loading low byte
move.b highByte(a6),glyphID(a6) ; save the high byte
move.b lowByte(a6),glyphID+1(a6) ; save the low byte
@singleByteFont
endif
MOVE.L WidthTabHandle, -(SP) ;2) Push the Width Table Handle onto the stack
PEA fontID(A6) ;1) Push the Glyph Rec Ptr
TST.B FASTFLAG(A6) ;WERE WE GOING DIRECT TO SCREEN ?
BEQ.S @skip32 ;NO, CONTINUE
TST.B needs32bit(A6) ;running 32 bit clean
BEQ.S @skip32 ;NOPE, so skip it
move.b MMUsave(a6),d0 ;get previous MMU state in d0
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
_sbRetrieveGlyph ;Call the routine via SplineDispatch
moveq #true32b,d0 ;switch to 32 bit addressing
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
BRA.S @skip24
@skip32
_sbRetrieveGlyph ;Call the routine via SplineDispatch
@skip24
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Re-establish pointers
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L WidthTabHandle,A0 ;Get the handle
MOVE.L (A0),widTabPtr(A6) ;restore the width table pointer
;The cacheHand may have change if we got
;Memory somewhere else
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; May have banded for memory
; restore advance width
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L widTabPtr(A6),A0 ;Point to the width table
MOVE.L 0(A0,D5*4),D4 ;GET FIXED POINT WIDTH
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
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.
MOVE.L splineKeyRec.cacheHand(A0),A0 ; Get the handle in case it changed.
MOVE.L A0, cacheHand(A6) ;restore cacheHand
MOVE.L (A0), D0 ;pointer to the cache
_StripAddress ;Make sure it is the right mode
MOVE.L D0, cachePtr(A6) ;restore cache pointer
MOVE.L D0, A2
LEA cache.glyphArray(A2), A0 ;Get array of glyphs into A0
MOVE.L A0, glyphArray(A6) ;restore the glyph array pointer
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
TST.L (SP)+ ;Any Errors
MOVEM.L (SP)+, A1/D2 ;Restore all registers on return
BNE sMiss ;No bitmap so print missing character
MOVE.L entryOffset(A6), D0
ADD.L D0, A2 ;Point to the data
MOVE.L srcAddr(A6), A4 ;Get the address
TST.B needs32bit(A6) ;running 32 bit clean
BEQ.S @no32 ;=>IF NOT, JUST RETURN
MOVEM.L A0-A1/D0-D2,-(SP) ;Save off all registers before JSR
MOVE.L A4, D0 ;get 24 bit base addr
_rTranslate24To32 ;mask off high byte
MOVE.L D0,A4 ;SAVE FOR LATER
MOVEM.L (SP)+, A0-A1/D0-D2 ;Restore all registers on return
@no32
MOVE.W yMax(A6), D6 ;Save yMax in D6
MOVE.W scan(A6), D7 ;Save the scan lines
MOVE.W yMin(A6), D3 ;Get ymin for later
MOVE.L srcRow(A6), D5 ;byteWidth in D5 for now <45-CEL>
BRA.S noClipping
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; End _sbRetrieveGlyph call
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
isCached
MOVE.L cachePtr(A6), A2 ;Get pointer to cache
ADD.L D0, A2 ;add offset and point to glyph data
if (hasDoubleByte) then
clr.l d0 ; clear a long for the character code
move.b lowByte(a6),d0 ; double byte character?
beq.s @haveGlyphRecord ; no, skip this
move.l 0(a2,d0.w*4),d0 ; load glyph record offset
ble errorOrNotCached ; fall into common error case
move.l cachePtr(a6),a2 ; load pointer to cache
add.l d0,a2 ; add offfset for glyph pointer
@haveGlyphRecord
endif
LEA glyph.cacheData(A2), A4 ;Get address
MOVE.W glyph.yMax(A2), D6 ;Save yMax in D6
MOVE.W glyph.scan(A2), D7 ;Save the scan lines
MOVE.W glyph.yMin(A2), D3 ;Save the scan lines
MOVE.L glyph.byteWidth(A2), D5 ;byteWidth in D2 for now <45-CEL>
TST.B clipVert(A6) ;are we clipping
BEQ.S noClipping ;nope so continue
MOVEQ #0, D1 ;d1 long ready
MOVE.W D6, D1 ;Get the bottom clipping area
SUB.W topClip(A6), D1 ;clipping value = yMax - topClip
BLE.S @noTopClip ;Top not clipped
MOVE.W topClip(A6), D6 ;New yMax from topclip value
MOVE.L glyph.byteWidth(A2), D0 ;
MULU D0, D1 ;Get Adjusment to srcAddr
ADD.L D1, A4 ;Add adjustment to top
@noTopClip
CMP.W botClip(A6), D3 ;get the bottom clipping value
BGE.S @noBotClip
MOVE.W botClip(A6), D3 ;get new ymin
@noBotClip
MOVE.W D6, D7 ;Get the YMax value
SUB.W D3, D7 ;scan = yMax - yMin
noClipping
SUBQ.W #1, D7 ;
BMI sMiss ;nothing to blit so skip character
MOVE.L CHARLOC(A6), D3 ;D3 = DestLeft (LSB + CharLoc)
SWAP D3 ;Only use low order word
ADD.W glyph.devLSB(A2), D3 ;Get integralized left side bearing
TST.B nextBand(A6) ;skip the advance???
BNE.S @noAdvance ;
;¥¥¥ spot for skipping advance if char banding!!!
IF HAS_COLOR | SCRIPT_CHAR_EXTRA THEN ;<7> CEL
ADD.L characterExtra(A6),D4 ;add in character extra, if any
ENDIF
ADD.L D4, CHARLOC(A6) ;Add fixed point width to CharLoc
@noAdvance
MOVE.W glyph.bitWidth(A2), D2 ;
MOVE.L D5, A2 ;byteWidth in A2 <45-CEL>
MOVE.W topAdjust(A6), D4 ;Use the topadjust previous calculated
SUB.W D6, D4 ;D4 is dest adjustment
MOVE.W D2, charWidth(A6) ;Save for later
ADD.W D3, D2 ;DSTRIGHT := DSTLEFT + WIDTH
MOVEQ #0, D1 ;D1 = SrcLeft for blit equals 0
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; On Entry
; Registers On Entry:
; D0 = scratch A0 = xxxxxxx
; D1 = SrcLeft.w A1 = xxxxxxx
; D2 = DstRight.w A2 = srcRow.l
; D3 = DstLeft.w A3 = xxxxxxx
; D4 = DstAdjust .w A4 = srcAddr.l
; D5 = xxxxxxx A5 = xxxxxxx
; D6 = yMax.w A6 = stack frame
; D7 = scan A7 = xxxxxxx
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;$$$ Horizontal Clipping
TST.B FastFlag(A6) ;ARE WE GOING FAST ?
BEQ.S sHORIZOK ;NO, DON'T CLIP
CMP MINRECT+LEFT(A6),D3 ;IS DSTLEFT < MINRECT.LEFT ?
BGE.S sLEFTOK ;NO, CONTINUE
CMP MINRECT+LEFT(A6),D2 ;IS DSTRIGHT <= MINRECT.LEFT ?
BLE sSKIPCH ;YES, SKIP THIS CHAR
sTRIMLFT MOVE MINRECT+LEFT(A6),D0 ;NO, GET MINRECT.LEFT
SUB D3,D0 ;DISCARD:=MINRECT.LEFT-DSTLEFT
ADD D0,D1 ;SRCLEFT:=SRCLEFT+DISCARD
ADD D0,D3 ;DSTLEFT:=DSTLEFT+DISCARD
CMP MINRECT+RIGHT(A6),D2 ;IS DSTRIGHT > MINRECT.RIGHT ?
BLE.S sfixCharWidth ;NO, CONTINUE
BRA.S sTRIMRT ;YES, TRIM RIGHT
sLEFTOK CMP MINRECT+RIGHT(A6),D2 ;IS DSTRIGHT <= MINRECT.RIGHT ?
BLE.S sHORIZOK ;YES, CONTINUE
CMP MINRECT+RIGHT(A6),D3 ;IS DSTLEFT >= MINRECT.RIGHT ?
BGE STRDONE ;YES, IGNORE REST OF STRING
sTRIMRT MOVE MINRECT+RIGHT(A6),D2 ;NO, TRIM DSTRIGHT
sfixCharWidth
MOVE D2,D0 ;char width has been trimmed left, right, or both
SUB D3,D0 ;so recalculate char width to draw
MOVE D0,charWidth(A6) ;and save this tidbit of info. for later
sHORIZOK
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Blit loop for the 68020+ machines
;
; Inputs to local block CharBlt:
;
; Registers Use:
; D0 = xxxxxxx A0 = xxxxxxx
; D1 = SrcLeft.l A1 = TextPtr.l
; D2 = DstRight.w A2 = srcRow.l
; D3 = DstLeft.w A3 = dstRow.w
; D4 = DstAdjust .w A4 = srcAddr.l
; D5 = xxxxxxx A5 = dstPtr.l
; D6 = yMax.w A6 = stack frame.l
; D7 = scan.w A7 = stack pointer.l
;
; dstLeft relative to buffer
; dstRight relative to buffer, > dstLeft
;
; CLOBBERS: D0,D1,D2,D3,D4,D5,D6,D7,A0,A2,A3,A4,A5
; PRESERVES: A1,A6,A7
;
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVEM D1-D3,maskBlts(A6)
MOVE.B textCopyMode(A6),orNotOK(A6) ;if copy or if mask mode, do bit moves instead of OR
ST notMaskPass(A6) ;use the bitDepth this pass
MOVE BUFROW(A6),A3
MOVE.L bufStart(A6), A5 ;BufStart (dst bitmap)
smaskBlt
; sfnt adjustment of the destination pointer
MOVE A3,D0 ;get dstRow in D-reg
MULS.W D4,D0 ;calc charTop * dstRow
ADD.L D0,A5 ;add to dstPtr
; Put glyph height - 1 into D7 for blit loop
;
ENDIF ;hasSplineFonts
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; Setup shift count in D5 (relative shift between src and dst)
;
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
pastBitMapPointers ;skipped past bitmap pointer setup
;
; figure alignment offset in source so that dest is long aligned
;
MOVEQ #$1F,D0 ;get a 5 bit mask, needed later
MOVE.L D1,D5
;
; Setup dstPtr in A5, address of leftmost dst word
;
MOVE.W D3,D6 ;GET A COPY OF DSTLEFT
ASR #5,D6 ;CONVERT FROM DOTS TO LONGS
MOVE.W D6,D4 ;copy dest left in longs for later
LSL #2,D6 ;quad for bytes
ADD.W D6,A5 ;move dest pointer to start of character
;
; figure number of longs to move
;
MOVE.W D2,D6 ;copy dstRight
ASR #5,D6
SUB.W D4,D6 ;if same, it fits into a single long
BEQ fitsInLong ;most 1 bit deep characters fit into a long
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; SPANS LONG
;
; Character spans long in destination, so it must be moved in pieces.
;
; Registers Use:
; D0 = 5 bit mask.w A0 = xxxxxxx
; D1 = SrcLeft.w A1 = TextPtr.l
; D2 = DstRight.w A2 = srcRow.l
; D3 = DstLeft.w A3 = destRow.l
; D4 = xxxxxxx A4 = srcRowPtr.l
; D5 = SrcLeft.w A5 = dstPtr.l
; D6 = longs to move.w A6 = stack frame.l
; D7 = scan.w A7 = stack pointer.l
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
NEG D3 ;negate for bit counting
AND D0,D3 ;get bottom 5 bits of dstLeft
BNE.S @skip32
MOVEQ #32,D3 ;if 0, make it 32
@skip32
MOVE.W D6,D4 ;total longs (not including left part)
LSL #2,D4 ;make it a byte count
SUB D4,A2 ;adjust source bump count
SUB D4,A3 ;adjust dest. bump count
SUBQ.W #1,D6 ;number of whole longs, less left & right parts
ADD D3,D1 ;the right hand start
MOVEQ #32,D4
SUB.L D4,D1
;
; if not 1 bit font & mode is not srcOr, do moves instead
;
TST.B orNotOK(A6)
BNE.S DoMove
;
; OR words to the screen; set up right mask
;
AND D0,D2 ;get bottom 5 bits of dstRight
MOVEQ #1,D4
ROR.L #1,D4 ;set the high bit
ASR.L D2,D4 ;$80000000 to $FFFFFFFF
ASL.L #1,D4 ;$00000000 to $FFFFFFFE
MOVE.W D6,D2 ;initialize whole long count
MOVE.W D6,A0 ;save long count for later
MOVE.L D5,D6
ADD.W D3,D6
MOVEQ #32,D0
SUB.L D0,D6
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; SLOW LOOP
;
; Slow loop only taken in wierd cases where dst wider than a long.
; Or the more common case that the font is more than 1 bit deep
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MAIN1
BFEXTU (A4){D5:D3},D0 ;GET SRC FROM BITMAP
BRA.S @checkLong ;see if there is some number of longs to do
@main2
BFEXTU (A4){D6:0},D0 ;GET SRC FROM BITMAP
@checkLong
OR.L D0,(A5)+ ;OR SRC INTO DST
ADDQ #4,A4 ;BUMP SRCPTR RIGHT
DBRA D2,@main2 ;LOOP TILL LAST long
BFEXTU (A4){D1:0},D0 ;GET SRC FROM BITMAP
AND.L D4,D0
OR.L D0,(A5) ;OR SRC INTO DST
ADD.L A2,A4 ;BUMP TO NEXT ROW
ADD.L A3,A5 ;BUMP DST TO NEXT ROW
WIDE1 MOVE A0,D2 ;GET long count
DBRA D7,MAIN1 ;LOOP ALL ROWS
BRA decCount ;skip mask blt part
;
; Handle case of drawing into the offscreen bit map in color separately
;
DoMove
MOVE D2,D4 ;copy dstRight
AND D0,D4 ;get bottom 5 bits of dstRight
MOVE D6,longCount(A6) ;save # of whole longs
MOVE D6,D2 ;set up first loop count
MOVE.L bkCol(A6),D6 ;get a long full of the background color
BFEXTU D6{0:D3},D0 ;background color & left mask
MOVE.L D0,leftBack(A6) ;save for quick compare
BFEXTU D6{0:D4},D0 ;background color & right mask
MOVE.L D0,rightBack(A6) ;right mask color compare
MOVE bitDepth(A6),D0 ;bits in a single pixel
BFEXTU D6{0:D0},D0 ;get a single pixel of the background color
MOVE D0,bkCol1(A6) ;a single background color for quick compare
MOVEQ #32,D6 ;
SUB D3,D6 ;
MOVE.L D5,A0
ADD D3,A0
SUB #32,A0 ;set up center move offset
;
; Slow loop taken in cases where dst wider than a long (common for fonts more than 1 bit
; deep.) Need to move only the pixels that are not colored same as background.
;
MoveLeft
BFEXTU (A5){D6:D3},D0 ;get current background of destination
CMP.L leftBack(A6),D0 ;compare it against the background color AND leftMask
BNE.S leftOnePix ;if different, must move 1 pixel at a time
;
; Here the destination has only background color pixels, so the whole thing can be moved
;
BFEXTU (A4){D5:D3},D0 ;GET SRC FROM BITMAP
BFINS D0,(A5){D6:D3}
checkLong
EXG A0,D5 ;set up center move offset
midChkLong
ADDQ #4,A5 ;bump destination
BRA.S checkMLong ;see if there is some number of longs to do
MoveMid
MOVE.L bkCol(A6),D0
CMP.L (A5),D0 ;same as background color?
BNE.S midOnePix ;if different, move 1 at a time
BFEXTU (A4){D5:0},D0 ;GET SRC FROM BITMAP
MOVE.L D0,(A5)+ ;OR SRC INTO DST
checkMLong
ADDQ #4,A4 ;BUMP SRCPTR RIGHT
DBRA D2,MoveMid ;LOOP TILL LAST WORD
MoveRight
EXG A0,D5 ;set up left move offset
TST D4
BEQ.S nextRow
BFEXTU (A5){0:D4},D0 ;look at the destination
CMP.L rightBack(A6),D0 ;compare it against the background AND rightMask
BNE.S rightOnePix ;if different, must move 1 pixel at a time
;
; Here the destination has only background color pixels, so the whole thing can be moved
;
BFEXTU (A4){D1:D4},D0 ;get the right part of the character
BFINS D0,(A5){0:D4} ;move it to the destination
nextRow
ADD.L A2,A4 ;BUMP TO NEXT ROW
ADD.L A3,A5 ;BUMP DST TO NEXT ROW
offMove
MOVE longCount(A6),D2 ;GET long count
DBRA D7,MoveLeft ;LOOP ALL ROWS
BRA decCount ;out of here for next char
;
; need to move only the pixels that are not colored same as background
;
leftOnePix
MOVEM.L D1/D3-D6,-(SP) ;save temporary registers
MOVEM bkCol1(A6),D0/D1 ;D0 = back color D1 = pixel width
@nxtPixel
BFEXTU (A4){D5:D1},D4 ;pick up a source pixel
CMP D4,D0 ;is it the same as the back color?
BEQ.S @skipInsert ;if so, donÕt add to destination
BFINS D4,(A5){D6:D1} ;if not, copy it to the destination
@skipInsert
ADD.L D1,D5 ;move to next source pixel
ADD D1,D6 ;move to next destination pixel
SUB D1,D3 ;decrement count
BGT.S @nxtPixel ;do until weÕre done
MOVEM.L (SP)+,D1/D3-D6 ;restore bkCol, left & right widths, src & dest offsets
BRA.S checkLong
midOnePix
MOVEQ #32,D0 ;full long size in bits
MOVEM.L D1/D3-D6,-(SP) ;save temporary registers
MOVEQ #0,D6
MOVEM bkCol1(A6),D1/D3 ;D1 = back color D3 = pixel width
@nxtPixel
BFEXTU (A4){D5:D3},D4 ;pick up a source pixel
CMP D4,D1 ;is it the same as the back color?
BEQ.S @skipInsert ;if so, donÕt add to destination
BFINS D4,(A5){D6:D3} ;if not, copy it to the destination
@skipInsert
ADD.L D3,D5 ;move to next source pixel
ADD D3,D6 ;move to next destination pixel
SUB D3,D0 ;decrement count
BGT.S @nxtPixel ;do until weÕre done
MOVEM.L (SP)+,D1/D3-D6 ;restore bkCol, left & right widths, src & dest offsets
BRA midChkLong
rightOnePix
MOVEM.L D1/D3-D6,-(SP) ;save temporary registers
MOVEQ #0,D6
MOVEM bkCol1(A6),D3/D5 ;D3 = back color D5 = pixel width
@nxtPixel
BFEXTU (A4){D1:D5},D0 ;pick up a source pixel
CMP D0,D3 ;is it the same as the back color?
BEQ.S @skipInsert ;if so, donÕt add to destination
BFINS D0,(A5){D6:D5} ;if not, copy it to the destination
@skipInsert
ADD.L D5,D1 ;move to next source pixel
ADD D5,D6 ;move to next destination pixel
SUB D5,D4 ;decrement count
BGT.S @nxtPixel ;do until weÕre done
MOVEM.L (SP)+,D1/D3-D6 ;restore bkCol, left & right widths, src & dest offsets
BRA nextRow
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; FASTER LOOPS
;
; Here, the character does not cross a long boundary, so faster loops are in order.
;
; Registers Use:
; D0 = 5 bit mask.w A0 = xxxxxxx
; D1 = src Offset.w A1 = TextPtr.l
; D2 = dstRight.w A2 = srcRowSize.l
; D3 = dstLeft.w A3 = destRowPtr.l
; D4 = xxxxxxx A4 = srcRowPtr.l
; D5 = src Offset.w A5 = destRowPtr.l
; D6 = longs to move.w A6 = stack frame.l
; D7 = scan.w A7 = stack Pointer.l
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
fitsInLong
MOVE.W charWidth(A6),D3 ;set up character width in bits
TST.B notMaskPass(A6) ;if dest is 1 bit, or this is the mask,
BEQ.S @skipMul ;then skip the mul scale
MOVE bitShift(A6),D4 ;set up bit depth
LSL D4,D3
@skipMul
TST.B orNotOK(A6) ;can we OR?
BNE.S offLong ;if not, bit extract/insert instead
;
; Optimize if dst fits in one long. (most 1 bit deep characters do)
;
LONG1
;
; OR words to the screen; set up right mask
MOVE D2,D1 ;copy dest right
NEG D1 ;figure not bits from left but bits from right
AND D0,D1 ;but only from 0 to 31
ADD D1,D3 ;add right mask to extract width
AND D0,D2 ;get bottom 5 bits of dstRight
MOVEQ #1,D4
ROR.L #1,D4 ;set the high bit
ASR.L D2,D4 ;$80000000 to $FFFFFFFF
ASL.L #1,D4 ;$00000000 to $FFFFFFFE
; if D5 + D3 < 32, use a faster set of code:
longLoop
BFEXTU (A4){D5:D3},D0 ;GET SRC DATA
AND.L D4,D0
OR.L D0,(A5) ;OR RESULT INTO DST
ADD.L A2,A4 ;BUMP SRCPTR TO NEXT ROW
ADD.L A3,A5 ;BUMP DSTPTR TO NEXT ROW
DBRA D7,longLoop ;LOOP ALL ROWS
BRA decCount
;
; Optimize if dst fits in one long. (most normal characters do)
;
offLong
MOVE D2,D6
AND.L D0,D6
SUB D3,D6
BFEXTU bkCol(A6){0:D3},D2
MOVEM.L D5/D6,leftOffset(A6) ;save source left, destination left offsets
MOVE D5,D0 ;source left offset less
ADD D3,D0 ; width of pixels to be moved
MOVE D0,longCount(A6) ; determines inner loop bounds
MOVE bitDepth(A6),D4 ;get source depth
BFEXTU D2{0:D4},D1 ;set up 1 pixel of background color
offLongLoop
; check to see if existing destination is untouched (equal to background) so that there is no
; concern about obliterating over a part of a character that kerns into this space.
BFEXTU (A5){D6:D3},D0 ;get the existing background
CMP.L D2,D0 ;is it background colored?
BEQ.S @okToBlast ;if so, it is safe to cut and fill
; inner loop taken if some kerning has occured so that bits can not be moved directly over bkground
@nxtPixel
BFEXTU (A4){D5:D4},D0
CMP D0,D1
BEQ.S @skipInsert
BFINS D0,(A5){D6:D4}
@skipInsert
ADD D4,D6
ADD D4,D5
CMP longCount(A6),D5 ;where to stop with the mask
BLT.S @nxtPixel
MOVEM.L leftOffset(A6),D5/D6 ;restore source left, destination left offsets
BRA.S @nextRow
; if no kerning, data can be moved without concern for what is already there.
@okToBlast
BFEXTU (A4){D5:D3},D0 ;GET SRC DATA
BFINS D0,(A5){D6:D3} ;move to destination
@nextRow
ADD.L A2,A4 ;BUMP SRCPTR TO NEXT ROW
ADD.L A3,A5 ;BUMP DSTPTR TO NEXT ROW
DBRA D7,offLongLoop ;LOOP ALL ROWS
;
; here, set up things for mask blt
;
; BRA.S decCount ;Always Branch
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; END Blit loop for the 68020+ machines
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
decCount
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6)
BEQ.S @1
TST.B nextBand(A6) ;another char band then call retrieve!!!
BNE sNextBand ;do the next char band
SUBQ.W #1,countCopy(A6) ;decrement partial draw character count
BGT sNextCh ;LOOP IF MORE CHARS LEFT
BRA.S STRDONE
ENDIF
@1 SUBQ.W #1,charsRemain(A6) ;decrement total character count
SUBQ.W #1,countCopy(A6) ;decrement partial draw character count
BGT NEXTCH ;LOOP IF MORE CHARS LEFT
;------
STRDONE
MOVE.L SAVEA5(A6),A5 ;RESTORE GLOBAL PTR
TST.B FASTFLAG(A6) ;WERE WE GOING DIRECT TO SCREEN ?
BEQ.S @1 ;NO, CONTINUE
TST.B needs32Bit(A6) ;device need 32-bit addressing <7Apr90 KON>
BEQ.S @0 ;=>IF NOT, JUST RETURN
move.b MMUsave(a6),d0 ;get previous MMU state in d0
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
@0 tst.b crsrFlag(a6) ;is dst to a screen <7Apr90 KON>
beq.s @NoShow ;no, then don't show cursor
_SHOWCURSOR ;YES, RESTORE CURSOR
@NoShow BRA GOHOME ;AND QUIT
@1 MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L THEPORT(A0),A3 ;GET CURRENT GRAFPORT
MOVE.L fontPtr(A0),A4 ;POINT TO FMOUTPUT
MOVE.L fmOutFontH(A4),A2 ;GET FONT HANDLE
MOVE.L (A2),A2 ;DE-REFERENCE IT
;
; Make buffer bold if necessary:
;
CKBOLD CLR D2 ;GET READY FOR BYTE
MOVE.B fmOutBold(A4),D2 ;GET NUMBER OF OVERSTRIKES
BRA.S NXTBOLD ;BOLD BUFFER IF ANY
BOLDIT MOVE.L BUFSTART(A6),A0 ;POINT TO START OF BUFFER
MOVE.L BUFSIZE(A6),D1 ;HOW MANY LONGS IN BUF
SUB D0,D0 ;CLEAR X-BIT
BOLDLP MOVE.L (A0),D0 ;GET ONE LONG
ROXR.L #1,D0 ;ROTATE RIGHT WITH EXTEND
OR.L D0,(A0)+ ;OR BACK INTO BUFFER
DBRA D1,BOLDLP ;LOOP ENTIRE BUFFER
NXTBOLD DBRA D2,BOLDIT ;LOOP FOR EACH OVERSTRIKE
;
; Slant the buffer if necessary:
; Work from bottom of buffer up, shifting each row right.
; Work right to left to avoid clobbering src.
;
MOVEQ #0,D2 ;GET READY FOR BYTE
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;is it a spline
BNE.S CHECKUL ;Splines already italic, no italic needed
ENDIF ;<1.6-11april89-CEL>
MOVE.B fmOutItalic(A4),D2 ;DO WE NEED ITALIC ?
BEQ.S CHECKUL ;NO, CONTINUE
MOVE.L BUFEND(A6),A1 ;DSTPTR:=END OF BUFFER
MOVE BUFROW(A6),D3 ;GET BUFFER ROWBYTES
SUB D3,A1 ;BACK UP DSTPTR TO END OF 2ND ROW
LSR #2,D3 ;LONGCNT:=ROWBYTES DIV 4
SUB #1,D3 ;LONGCOUNT-1 FOR DBRA LOOP
MOVE sHeight(A6),D6 ;INIT ROW COUNTER
SUB #1,D6 ;Baseline not slanted <38>
MOVEQ #0,D4 ;INIT OFFSET
BRA.S DOSLANT ;GO TO LOOP START
NXTROW ADD.L D2,D4 ;OFFSET:=OFFSET+ITALIC
MOVE.L D4,D5 ;COPY OFFSET
LSR.L #4,D5 ;DELTA := OFFSET SCALED BY 16
NEG.L D5 ;make negative for BFEXTU
MOVE.L A1,A0 ;SRCPTR:=DSTPTR
SUB #4,A0 ;POINT TO LAST LONG
MOVE D3,D1 ;INIT LOOP TO LONGCNT
NXTLONG BFEXTU (A0){D5:0},D0 ;GET A SHIFTED LONG OF SRC
SUB #4,A0 ;BUMP SRCPTR LEFT ONE LONG
MOVE.L D0,-(A1) ;STORE IN DST AND BUMP DSTPTR
DBRA D1,NXTLONG ;LOOP ALL LONG THIS ROW
DOSLANT DBRA D6,NXTROW ;LOOP FOR ALL ROWS IN BUFFER
;
; Underline characters in buffer if necessary.
;
; Use characters in buffer to hide parts of the underline.
;
CHECKUL
TST.B fmOutULThick(A4) ;IS ULTHICK ZERO ?
BEQ NOTUL ;YES, CONTINUE
MOVE.L BUFSTART(A6),A0 ;POINT TO BUFFER START
MOVE BUFROW(A6),D1 ;GET BYTES PER ROW OF BUFFER
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;is it a spline
BEQ.S @doOldAssign ;Splines already stretch, no stretchbits needed
MOVE topClip(A6), D0 ;Use topClip and botClip since this is real size of buffer
TST.W D0
BLT.S NOTUL ;If ascent is negative do not do it
MOVE botClip(A6), D2 ;Real size of buffer
BRA.S @skipOldAssign
@doOldAssign
ENDIF ;<1.6-11april89-CEL>
MOVE sASCENT(A6),D0 ;stack ascent
MOVE sDESCENT(A6),D2 ;
@skipOldAssign
MULU D1,D0
ADD.L D0,A0 ;POINT TO BASELINE ROW
MOVE.L A0,A1
MOVE.L A0,A2
ADD D1,A1 ;POINT TO BASELINE+1
CMP #-2,D2 ;IS DESCENT AT LEAST 2 ?
BGT.S NOTUL ;NO, SKIP UNDERLINE
BEQ.S ONLY2 ;ONLY USE 2 IF DESCENT=2
ADD D1,A2
ADD D1,A2 ;POINT TO BASELINE+2
ONLY2 SUB D1,SP ;ALLOCATE TEMP SCANBUF
MOVE.L A3,-(SP) ;SAVE GRAFPORT
LEA 4(SP),A3 ;POINT TO START OF TEMP
LSR #2,D1 ;CONVERT BYTES TO LONGS
SUB #1,D1 ;INIT DBRA LOOP COUNT
MOVE D1,D2 ;COPY LOOP COUNT
SUB D0,D0 ;CLEAR X-BIT
UL1 MOVE.L (A0)+,D0 ;GET FROM BASELINE
OR.L (A1)+,D0 ;OR WITH BASELINE+1
OR.L (A2)+,D0 ;OR WITH BASELINE+2
MOVE.L D0,(A3) ;PUT RESULT TO TEMP
ROXR.L #1,D0 ;SHIFT WITH CARRY
OR.L D0,(A3)+ ;OR INTO TEMP
DBRA D1,UL1 ;LOOP ALL LONGS IN ROW
MOVE.L A1,A0 ;COPY END PTR
SUB D0,D0 ;CLEAR X-BIT
UL2 MOVE.L -(A3),D0 ;GET FROM TEMP
ROXL.L #1,D0 ;SHIFT LEFT WITH CARRY
OR.L (A3),D0 ;OR WITH TEMP
NOT.L D0 ;INVERT
OR.L D0,-(A1) ;DRAW SOME UNDERLINE
DBRA D2,UL2 ;LOOP ALL LONGS IN ROW
MOVE.L (SP)+,A3 ;RESTORE GRAFPORT
;
; Setup fakeRgn, a dummy rectangular region
;
NOTUL MOVE #10,FAKERGN+RGNSIZE(A6) ;SIZE=10 BYTES FOR RECT RGN
MOVE.L DSTPIX+BOUNDS(A6),FAKERGN+RGNBBOX(A6)
MOVE.L DSTPIX+BOUNDS+4(A6),FAKERGN+RGNBBOX+4(A6)
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;is it a spline
BEQ.S @skipBandClip ;
TST.B clipVert(A6) ;Can we try the fast blitting routine???
BEQ.S @skipBandClip ;go to clipping blit loop
MOVE.W TEXTR2(A6), D1 ;get top
MOVE.W D1, D2 ;Make a copy
MOVE.W sAscent(A6), D0 ;place in reg for compare
SUB.W origTopClip(A6), D0 ;
BNE.S @topIsClipped ;top is clipped so do not add shadow extra
TST.B fmOutShadow(A6) ;no shadowing so skip adjustment for it
BEQ.S @noShadowSUB
SUB.W #1, D1 ;adding to ymax value
@noShadowSUB
BRA.S @gotNewTop
@topIsClipped
ADD.W D0, D1
@gotNewTop
MOVE.W D1, FAKERGN+RGNBBOX+TOP(A6) ;Fake top
MOVE.W origBotClip(A6), D0 ;get the bottom clip
CMP.W sDescent(A6), D0 ;are they the same
BNE.S @noExtra ;no extra for shadow
TST.B fmOutShadow(A6) ;no shadowing so skip adjustment for it
BEQ.S @noExtra
SUB.W #2, D0 ;add in for shadow
@noExtra
MOVE.W sAscent(A6), D1 ;place in reg for compare
SUB.W D0, D1 ;subtract bottom clip
ADD.W D1, D2 ;Add to TextR2 top
MOVE.W D2, FAKERGN+RGNBBOX+BOTTOM(A6) ;Fake bottom
ENDIF ;
@skipBandClip
LEA FAKERGN(A6),A0 ;GET ADDR OF FAKERGN
MOVE.L A0,FAKEPTR(A6) ;POINT FAKE MASTERPTR TO IT
;
; SET UP SOURCE BITMAP TO TRANSFER TO SCREEN
;
; SRCPIX := buffer
;
LEA SRCBITS(A6),A0 ;POINT TO source bits
MOVE.L A0,A1
MOVE.L BUFSTART(A6),(A0)+ ;SET UP BASEADDR
MOVE BUFROW(A6),(A0)+ ;SET UP ROWBYTES
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;is it a spline
BEQ.S @skipAdjust ;Splines already stretch, no stretchbits needed
MOVE sAscent(A6), D0 ;Get the ascent in D0
SUB topClip(A6), D0 ;What is the difference for adjustment
ADD TEXTRECT+TOP(A6),D0 ;SET UP BOUNDS TOP
MOVE D0,(A0)+ ;SET UP BOUNDS TOP
BRA.S @skipNorm
@skipAdjust
MOVE TEXTRECT+TOP(A6),(A0)+ ;SET UP BOUNDS TOP
@skipNorm
ELSE
MOVE TEXTRECT+TOP(A6),(A0)+ ;SET UP BOUNDS TOP
ENDIF ;NEW
MOVE BUFLEFT(A6),(A0)+ ;SET UP BOUNDS LEFT
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;is it a spline
BEQ.S @skipTheAdjust ;Splines already stretch, no stretchbits needed
MOVE sAscent(A6), D0 ;Get the ascent in D0
SUB topClip(A6), D0 ;What is the difference for adjustment
ADD.W TEXTRECT+BOTRIGHT(A6), D0 ;Get the bottom
MOVE.W D0,(A0)+ ;SET UP BOTTOM
MOVE.W TEXTRECT+RIGHT(A6), (A0)+ ;Set up right
BRA.S @skipNormPath
@skipTheAdjust
MOVE.L TEXTRECT+BOTRIGHT(A6),(A0)+ ;SET UP BOTTOM RIGHT
@skipNormPath
ELSE ;
MOVE.L TEXTRECT+BOTRIGHT(A6),(A0)+ ;SET UP BOTTOM RIGHT
ENDIF ;
LEA SRCPIX(A6),A2
_BitsToPix
TST.B maskFont(A6)
BEQ @finishSrcPix ; <CEL-39>
LEA maskBits(A6),A0 ;POINT TO mask bits
MOVE.L maskStart(A6),(A0)+ ;SET UP BASEADDR
MOVE mBufRow(A6),(A0)+ ;SET UP ROWBYTES
MOVE TEXTRECT+TOP(A6),(A0)+ ;SET UP BOUNDS TOP
MOVE BUFLEFT(A6),(A0)+ ;SET UP BOUNDS LEFT
MOVE.L TEXTRECT+BOTRIGHT(A6),(A0)+ ;SET UP BOTTOM RIGHT
TST bitShift(A6) ;is the bit depth 1? <CEL-39>
BEQ.S @finishSrcPix
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; make fill loop <CEL-39>
;
; Registers Use:
; D0 = xxxxxxx A0 = SrcPtr
; D1 = temp WidthInPixels A1 = DstPtr
; D2 = (2**PixelSize)-1.w A2 = Src rowBytes.l
; D3 = Dst Offset A3 = Dest rowBytes.w
; D4 = Src Offset A4 = xxxxxxx
; D5 = Src PixelSize.w A5 = xxxxxxx
; D6 = Height.w A6 = xxxxxxx
; D7 = Width In Pixels A7 = xxxxxxx
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
MOVE.L A3, -(SP) ;Save A3
MOVE.W bitDepth(A6), D5 ;bits per pixel
MOVEQ #1, D2 ;2 to be shifted
LSL.W D5, D2 ;2**Pixel Size
SUB.W #1, D2 ;(2*PixelSize)-1
MOVE.W sHeight(A6), D6 ;
SUB.W #1, D6 ;for the dbra
MOVE.W mBufRow(A6), A3 ;row bytes of mask
MOVE.W A3,D7 ;Shift by pixel depth
LSL.W #3, D7 ;pixels=rowbytes*8
SUB.W #1, D7 ;for dbra
MOVE.L bufStart(A6), A0 ;SrcPtr
MOVE.L maskStart(A6), A1 ;DstPtr
MOVE.W bufRow(A6), A2 ;Src rowBytes
@nxtScan
MOVE.W D7, D1 ;D1 for loop of the width
MOVEQ #0, D3 ;Clear offset
MOVEQ #0, D4 ;Clear offset
@nxtPix
BFEXTU (A0){D4,D5}, D0 ;get a pixel
ADD.W D2, D0 ;create a carry bit if non zero
LSR.W D5, D0 ;Shift to get black pixel in bottom
BFINS D0, (A1){D3,1} ;Insert the bit into the mask
ADD.W D5, D4 ;Increment the offset
ADDQ #1, D3 ;Increment mask Pixel offset
DBRA D1, @nxtPix ;cont to next pixel
ADD.L A2, A0 ;bump to next row
ADD.W A3, A1 ;bump to next row
DBRA D6, @nxtScan ;cont to next scan
MOVE.L (SP)+, A3 ;Restore A3
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
@finishSrcPix
TST bitShift(A6) ;is the bit depth 1? <CEL-44>
BEQ.S @skipColorJam ; <CEL-44>
MOVE bitDepth(A6),srcPix+pixelSize(A6) ;set up bit depth <CEL-44>
MOVE bitDepth(A6),srcPix+cmpSize(A6) ;set up bit depth <CEL-44>
MOVE.L dstPix+pmTable(A6),srcPix+pmTable(A6) ;set up color table <CEL-44>
TST.B synFont(A6) ;is it a syn font??? <CEL-44>
BNE.S @skipColorJam ;use the dest color table <CEL-44>
MOVE.L WidthTabHandle,A0 ;Get the handle <CEL-44>
MOVE.L (A0), A0 ;Ptr <CEL-44>
MOVE.L widthNFNT(A0),D0 ;get resource ID in low word, NFNT bit in high word <CEL-44>
SUBQ #4,SP ;make space for function result <CEL-44>
MOVE.L #'fctb',-(SP) ;pass resource type <CEL-44>
MOVE D0,-(SP) ;pass resource ID <CEL-44>
_GetResource ;only uses D0,A0 <CEL-44>
MOVE.L (SP)+,D0 ;if it fails, then no color table to pass to MakeScaleTbl <CEL-44>
BEQ.S @skipColorJam ; <CEL-44>
MOVE.L D0,srcPix+pmTable(A6) ;set up color table, if any <CEL-44>
@skipColorJam
;
; check if any shadowing:
;
CLR D3 ;GET READY FOR BYTE
MOVE.B fmOutShadow(A4),D3 ;GET SHADOW COUNT
BEQ NOSHAD ;SKIP IF NO SHADOWING
;
; Shadowing will be used. Allocate buf2, 4 scans taller than BUF1.
; Clear out new 4 scanlines, and copy BUF1 into the rest.
;
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6)
BEQ.S oldAlloc2 ;Go to old way of allocating
MOVE.L currentEnd(A6), A0 ;Get the current end of the buffer
CLR.L (A0)+ ;ALLOW ONE LONG OF SLOP
MOVE.L A0, buf2Start(A6) ;REMEMBER START OF BUF2
MOVE.L bufStart(A6),A1 ;POINT to first buffer
MOVE.L bufSize(A6),D0 ;GET NUMBER OF LONGS IN BUF1
SUB.L #1,D0 ;INIT DBRA COUNTER
MOVE.L D0, D1 ;Get copy of size
SWAP D1 ;Get high order word for outer loop
CpyBuff MOVE.L (A1)+,(A0)+ ;COPY FROM BUF1 TO NEW BUF2
DBRA D0,CpyBuff ;COPY ALL OF BUF1
DBRA D1,CpyBuff ;COPY ALL OF BUF1
CLR.L (A0)+ ;ALLOW ONE LONG OF SLOP
MOVE BUFROW(A6),D0 ;GET 4 * NUMBER OF LONGS PER ROW
SUB #1,D0 ;INIT LOOP COUNTER
clrBuf2 CLR.L (A0)+ ;ALLOCATE AND CLEAR A LONG
DBRA D0,clrBuf2 ;CLEAR 4 SCANLINES WORTH
MOVE.L A0, buf2End(A6) ;REMEMBER END OF BUF2
CLR.L (A0)+ ;ALLOW ONE LONG OF SLOP
BRA.S doneNEW2
oldAlloc2
MOVE BUFROW(A6),D0 ;GET 4 * NUMBER OF LONGS PER ROW
SUB #1,D0 ;INIT LOOP COUNTER
CLR.L -(SP) ;ALLOW ONE LONG OF SLOP
MOVE.L SP,BUF2END(A6) ;REMEMBER END OF BUF2
CLR2 CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
DBRA D0,CLR2 ;CLEAR 4 SCANLINES WORTH
MOVE.L BUFSIZE(A6),D0 ;GET NUMBER OF LONGS IN BUF1
SUB #1,D0 ;INIT DBRA COUNTER
MOVE.L BUFEND(A6),A0 ;POINT TO END OF BUF1
COPYLP MOVE.L -(A0),-(SP) ;COPY FROM BUF1 TO NEW BUF2
DBRA D0,COPYLP ;COPY ALL OF BUF1
MOVE.L SP,BUF2START(A6) ;REMEMBER START OF BUF2
CLR.L -(SP) ;ALLOW ONE LONG OF SLOP
doneNEW2
ELSE
MOVE BUFROW(A6),D0 ;GET 4 * NUMBER OF LONGS PER ROW
SUB #1,D0 ;INIT LOOP COUNTER
CLR.L -(SP) ;ALLOW ONE LONG OF SLOP
MOVE.L SP,BUF2END(A6) ;REMEMBER END OF BUF2
CLR2 CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
DBRA D0,CLR2 ;CLEAR 4 SCANLINES WORTH
MOVE.L BUFSIZE(A6),D0 ;GET NUMBER OF LONGS IN BUF1
SUB #1,D0 ;INIT DBRA COUNTER
MOVE.L BUFEND(A6),A0 ;POINT TO END OF BUF1
COPYLP MOVE.L -(A0),-(SP) ;COPY FROM BUF1 TO NEW BUF2
DBRA D0,COPYLP ;COPY ALL OF BUF1
MOVE.L SP,BUF2START(A6) ;REMEMBER START OF BUF2
CLR.L -(SP) ;ALLOW ONE LONG OF SLOP
ENDIF
;
; Bold buf2 across to the right enough for shadow.
;
AND #3,D3 ;RESTRICT SHADOW COUNT TO 1..3
MOVE D3,D2 ;INIT BOLD COUNTER
ACROSS1 MOVE.L BUF2START(A6),A0 ;POINT TO START OF BUFFER2
MOVE.L BUFSIZE(A6),D1 ;Init for first time of inner loop
MOVE.L D1,D4 ;Get copy of bufSize
SWAP D4 ;Get high order word
SUB D0,D0 ;CLEAR X-BIT
outAcross
ACROSS2 MOVE.L (A0),D0 ;GET A LONG FROM BUF2
ROXR.L #1,D0 ;SHIFT IT RIGHT EXTENDED
OR.L D0,(A0)+ ;OR IT BACK INTO BUFFER
DBRA D1,ACROSS2 ;LOOP FOR ALL LONGS
DBRA D4,outAcross ;Outer loop for inner loop
DBRA D2,ACROSS1 ;BOLD RIGHT 2,3, OR 4 TIMES
;
; Bold BUF2 down enough for shadow.
;
MOVE.L BUF2START(A6),A2 ;GET LIMIT POINTER
DOWN1 MOVE.L BUF2END(A6),A1 ;DSTPTR:=END OF BUF2
MOVE.L A1,A0
MOVE SRCBITS+ROWBYTES(A6),D2 ;GET SRC ROWBYTES
SUB D2,A0 ;SRCPTR:=END - 1 SCANLINE
DOWN2 MOVE.L -(A0),D0 ;GET A LONG FROM LINE ABOVE
OR.L D0,-(A1) ;OR INTO THIS LINE
CMP.L A2,A0 ;IS SRCPTR <= BUF2START ?
BGT.S DOWN2 ;NO, LOOP ALL LONGS
DBRA D3,DOWN1 ;BOLD DOWN 2,3, OR 4 TIMES
; XOR the plain text into the shadow buffer
MOVE.L bufStart(A6),A0 ;start of plain text
MOVE.L A2,A1 ;start of shadowed text
ADD D2,A1 ;bump down a line in the shadowed text
MOVE.L bufSize(A6),D1 ;size of buffers in longs
MOVE.L D1,D2 ;Get a copy of size
SWAP D2 ;Get high word of long
SUB D0,D0 ;clear x bit
@xor
MOVE.L (A0)+,D0 ;a line of plain text
ROXR.L #1,D0 ;shift it right, extended
EOR.L D0,(A1)+ ;combine with shadowed text
DBRA D1,@xor ;repeat for all longs
DBRA D2,@xor ;repeat outer loop with high order word
;
; Alter SRCBITS to use BUF2
;
MOVE.L A2,SRCBITS+BASEADDR(A6) ;SRC BASEADDR:=BUF2START
ADD #4,SRCBITS+BOUNDS+BOTTOM(A6) ;4 SCANS TALLER
;
; Push params and call StretchBits to transfer shadow to screen
;
MOVE.L TEXTRECT(A6),SRCRECT(A6) ;DSTRECT := SRCRECT
MOVE.L TEXTRECT+4(A6),SRCRECT+4(A6)
ADD #4,SRCRECT+BOTTOM(A6) ;PLUS 4 SCANS TALLER
MOVE.L SRCRECT(A6),DSTRECT(A6)
MOVE.L SRCRECT+4(A6),DSTRECT+4(A6)
LEA DSTRECT+TOP(A6),A0 ;OFFSET BY (-1,-1)
SUB #1,(A0)+ ;TOP
SUB #1,(A0)+ ;LEFT
SUB #1,(A0)+ ;BOTTOM
SUB #1,(A0)+ ;RIGHT
TST.B STRETCH(A6)
BEQ.S @1
PEA DSTRECT(A6)
PEA FROMRECT(A6)
PEA TORECT(A6)
_MAPRECT ;THEN MAPPED FOR SCALING
@1
PEA SRCBITS(A6) ;PUSH SRCPIX
MOVE.L maskBitsPtr(A6),-(SP) ;a mask?
BEQ.S @noMask
MOVE.L 4(SP),(SP) ;replace mask with copy of source
@noMask
PEA PORTBITS(A3) ;TRANSFER TO SCREEN
IF Gaudi THEN ;fix intersection if ColorQD and Bass init
TST.B isSpline(A6) ;is it a spline
BEQ.S @doOld ;skip special stretchbit fix
TST.B repeatBands(A6) ;if not banding then do nothing
BEQ.S @doOld
PEA DSTRECT(A6) ;PUSH DSTRECT = TEXTR2
PEA FAKERGN+RGNBBOX(A6) ;
MOVE #2,-(SP) ;PUSH NRECTS=4
PEA FAKERGN+RGNBBOX(A6) ;Place results in FakRgn
_RSECT ;CALC INTERSECTION
MOVE.L FAKERGN+RGNBBOX(A6), trimSrcRect(A6)
MOVE.L FAKERGN+RGNBBOX+4(A6), trimSrcRect+4(A6)
PEA trimSrcRect(A6) ;Make new source rect for Banding
PEA DSTRECT(A6)
PEA SRCRECT(A6)
_MAPRECT ;THEN MAPPED FOR SCALING
PEA trimSrcRect(A6) ;Make new source rect for Banding
IF HAS_COLOR THEN
PEA trimSrcRect(A6) ;maskRect same as source rect
ENDIF
PEA FAKERGN+RGNBBOX(A6) ;Use calculated dst rect
BRA.S @contArgs
ENDIF
@doOld PEA SRCRECT(A6) ;PUSH SRCRECT = TEXTRECT
PEA SRCRECT(A6) ;maskRect same as source rect
PEA DSTRECT(A6) ;PUSH DSTRECT = TEXTR2
@contArgs
MOVE locMode(A6),-(SP) ;PUSH TEXTMODE
TST.B doDither(A6) ;Should we add in Dither??? <CEL-39>
BEQ.S @noDither ; <CEL-39>
OR.W #$40, (SP) ;Or in the dither bit <CEL-39>
@noDither
CLR.L -(SP) ;NO PATTERN FOR NOW
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN HANDLE
MOVE.L VISRGN(A3),-(SP) ;PUSH VISRGN HANDLE
PEA FAKEPTR(A6) ;PUSH FAKE HANDLE
CLR -(SP) ;pass multicolor flag false
_StretchBits ;TRANSFER BUFFER TO SCREEN
; if old port, srcOr, draw center part in bic; if bic, in srcOr
; (This is done for compatibility with older applications like MacProject and MacDraw that
; expect to put text on an arbitrary background, relying on the center of the shadow to show.)
TST portBits+rowBytes(A3) ;a new port?
BMI GOHOME
MOVE locMode(A6),D0
CMP #srcOr,D0
BEQ.S @useBic
CMP #srcBic,D0
BNE GOHOME
@useBic
; restored altered srcBits
MOVE.L bufStart(A6),srcBits+baseAddr(A6)
SUB #4,srcBits+bounds+bottom(A6)
; adjust params for center portion StretchBits
CLR.L maskBitsPtr(A6) ;no mask
EOR #2,D0 ;change or to bic, bic to or
MOVE D0,locMode(A6) ;adjust textmode
;
; Push params and call StretchBits to transfer buffer to screen
;
NOSHAD
PEA SRCPIX(A6) ;PUSH SRCBITS
MOVE.L maskBitsPtr(A6),-(SP) ;may be 0 if no mask bitmap
PEA PORTBITS(A3) ;TRANSFER TO SCREEN
IF Gaudi THEN
TST.B isSpline(A6) ;is it a spline
BEQ @doOld ;skip special stretchbit fix
TST.B repeatBands(A6) ;if not banding then do nothing
BEQ.S @doOld
PEA TEXTR2(A6) ;PUSH DSTRECT = TEXTR2
PEA FAKERGN+RGNBBOX(A6) ;
MOVE #2,-(SP) ;PUSH NRECTS=2
PEA FAKERGN+RGNBBOX(A6) ;Place results in FakRgn
_RSECT ;CALC INTERSECTION
MOVE.L FAKERGN+RGNBBOX(A6), trimSrcRect(A6)
MOVE.L FAKERGN+RGNBBOX+4(A6), trimSrcRect+4(A6)
PEA trimSrcRect(A6) ;Make new source rect for Banding
PEA TEXTR2(A6)
PEA TEXTRECT(A6)
_MAPRECT ;THEN MAPPED FOR SCALING
PEA trimSrcRect(A6) ;Make new source rect for Banding
PEA trimSrcRect(A6) ;maskRect same as source rect
PEA FAKERGN+RGNBBOX(A6) ;Use calculated dst rect
BRA.S @contArgs
ENDIF
@doOld PEA TEXTRECT(A6) ;PUSH SRCRECT = TEXTRECT
PEA TEXTRECT(A6) ;maskRect same as source rect
PEA TEXTR2(A6) ;PUSH DSTRECT = TEXTR2
@contArgs
MOVE locMode(A6),-(SP) ;PUSH TEXTMODE
TST.B doDither(A6) ;Should we add in Dither??? <CEL-39>
BEQ.S @noDither ; <CEL-39>
OR.W #$40, (SP) ;Or in the dither bit <CEL-39>
@noDither
CLR.L -(SP) ;NO PATTERN FOR NOW
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN HANDLE
MOVE.L VISRGN(A3),-(SP) ;PUSH VISRGN HANDLE
PEA FAKEPTR(A6) ;PUSH FAKE HANDLE
; <07JUN92 SAH>
; The new way for text. The old multColor is now a bitfield, where bit 0 means that the
; src is Black/White only. multColor is now called drawFlags.
moveq #0,d0 ; clear all flags <08JUN92 SAH>
tst.b colorSource(a6) ; is it in fact color <08JUN92 SAH>
bne.s @setColor ; yes, so set bit color mapped bit <08JUN92 SAH>
moveq #1,d0 ; set b/w src bit <08JUN92 SAH>
bra.s @callStretch ; and draw it <08JUN92 SAH>
@setColor
moveq #2,d0 ; set color mapped bit <08JUN92 SAH>
@callStretch
move.w d0,-(sp) ; push drawFlags <08JUN92 SAH>
_StretchBits ;TRANSFER BUFFER TO SCREEN
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
; We are done so letÕs cleanupÉ
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
GOHOME
MOVE.L saveStk(A6),SP ;throw away the buffers
IF (hasSplineFonts) OR (Gaudi) THEN ; <31> DTY
TST.B isSpline(A6) ;is it a spline
BEQ @checkBitDivide ;skip spline cleanup
TST.W repeatBands(A6) ;repeat bands left
BEQ @splineClean ;we are done if none
MOVE.L clipStorage(A6), SP ;Save Address on variable for later cleanup
MOVE.W (SP)+, topClip(A6) ;Get new topClip
MOVE.W (SP)+, botClip(A6) ;Get new botClip
MOVE.W origCharCount(A6),D1 ;Re-Assign count
MOVE.W D1,countCopy(A6) ;Re-Assign count
MOVE stackOffset(A6),D0 ;either zero if stack was long aligned, or two if not
MOVE.W D1,count(A6,D0) ;Re-Assign count
MOVE.L SAVEA5(A6),A5 ;RESTORE GLOBAL PTR
MOVE.L grafGlobals(A5),A4 ;set up grafGlobals pointer for getting real width
MOVE.L fontPtr(A4),A4 ;POINT TO FMOUTPUT
MOVE txMode(A3),D0
AND #$FFF7,D0 ;clear pattern bit (let stretch reject invalid modes)
MOVE D0,locMode(A6) ;initialize copy
MOVE.L PENLOC(A6), PNLOC(A3) ;RESTORE PNLOC TO ORIGINAL
IF hasPenFraction THEN
move.l grafGlobals(a5),a0 ; load quickDraw globals.
move.w penLocFixed(a6),pnLocFixed(a0) ; restore fractional pen location.
ENDIF
TST PORTBITS+ROWBYTES(A3) ; is it a new port?
BPL.S @useOld3 ; no, no fraction to restore
MOVE PenLocHFrac(A6),pnLocHFrac(A3) ;restore fraction if applicable
@useOld3
MOVE.B saveHilite(A6),HiliteMode ;restore hilite bit
SUBQ.W #1, repeatBands(A6) ;Decrement band count
ADDQ.L #4, clipStorage(A6) ;Bump by a long for next top and Bottom clip
BRA NOTFAST ;Go and band the sucker encore
@splineClean
TST.L stackHandle(A6) ;Does it exist
BEQ.S @cleanUp
MOVE.L stackHandle(A6), A0 ;Get the handle in A0 for dispose routine
_HUnlock ;Unlock the baby
_DisposHandle ;Get rid of memory
BRA.S @cleanUp
ENDIF ;<1.6-11april89-CEL>
@checkBitDivide
MOVE charsRemain(A6),D0
SUB countCopy(A6),D0
MOVE D0,charsRemain(A6) ;if iterative, this will be greater than zero
BGT secondHalf ;so there are more characters to draw
@cleanUp
BSET #hiliteBit,HiliteMode ;reset hilite override, in case colormap was skipped
MOVEM.L (SP)+,D0-D7/A1-A4 ;RESTORE REGS
TST.W stackOffset(A6) ;was the stack aligned?
UNLK A6
BEQ.S @skipAlign
ADDQ #2,SP
@skipAlign
RTD #PARAMSIZE ;Return and pop the stack <1.6-11april89-CEL>
ENDPROC
CalcCharExtra PROC EXPORT
;------------------------------------------
;
; CalcCharExtra, given a 4.12 fixed point in D0 for a 1 point font, scales by the
; actual font point size, and by the scaling numerator and denominator returned by
; the font manager. The scaled extra is returned in 16.16 format in D0. Here the
; charExtra * size is scaled by denom/numer, since stretch will scale the resulting
; widths by numer/denom. Called by StdTxWidth, DrawText, TextMeasure.
;
; FMInNumer.h FOutDenom.h
; charExtra = ÑÑÑÑÑÑÑÑÑÑÑ * ÑÑÑÑÑÑÑÑÑÑÑ * input charExtra * requested pt. size
; FMInDenom.h FOutNumer.h
fSize EQU $40E ;sorry, no width table offsets in globals (yet)
MOVEM.L D1-D2/A0-A1,-(SP) ;preserve registers
SUB.W #8,SP ;make space on stack for final fixMul and first fixMul
MOVE.L D0,-(SP) ;push input charExtra
MOVE.L WidthPtr,A0 ;point at width table
MOVEQ #0,D0 ;zero high word
MOVE fSize(A0),D0 ;scale up by requested point size
SWAP D0 ;make into a fixed point number
MOVE.L D0,-(SP) ;push requested point size
_FixMul ;product on stack is charExtra * point size
SUB #8,SP ;make room for result of fixRatio and next fixMul
MOVE.W CurFMNumer+H,-(SP) ;push x input numer
MOVE.W CurFMDenom+H,-(SP) ;push x input denom
_FixRatio ;compute ratio input numer/denom
SUBQ #4,SP ;make space for result
MOVE.W FOutDenom+H,-(SP) ;push x output denom
MOVE.W FOutNumer+H,-(SP) ;push x output numer
_FixRatio ;compute ratio output denom/numer
_FixMul ;calculate scale factor
_FixMul ;scale by input charExtra
MOVEM.L (SP)+,D0-D2/A0-A1 ;get result in D0, restore registers
RTS ;home, James
ENDPROC
CASE OFF