home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
073.lha
/
XText
/
xtextsup.c
< prev
Wrap
C/C++ Source or Header
|
1987-06-02
|
16KB
|
500 lines
/* *** xtextsup.c ***********************************************************
*
* XText -- Support Procedures
* from Book 1 of the Amiga Programmers' Suite by RJ Mical
*
* Copyright (C) 1986, 1987, Robert J. Mical
* All Rights Reserved.
*
* Created for Amiga developers.
* Any or all of this code can be used in any program as long as this
* entire notice is retained, ok? Thanks.
*
* HISTORY NAME DESCRIPTION
* ----------- -------------- --------------------------------------------
* 27 Oct 86 RJ Add XText buffer stuff, prepare for release
* March 86 RJ Incorporated this code in Sidecar
* 26 Jan 86 RJ Mical Created this file (on my birthday!)
*
* *********************************************************************** */
#include "xtext.h"
VOID UnmakeXTextSupport();
struct TextAttr DefaultXTextFont =
{
(UBYTE *)"topaz.font",
TOPAZ_EIGHTY,
0,
FS_NORMAL
};
UBYTE *AllocXTextPlane(xtext)
struct XTextSupport *xtext;
/* This routine allocates an XText text plane, with one byte for each
* line of each character in the widest allowable line.
*/
{
return (AllocRemember(&xtext->XTextKey,
xtext->MaxTextWidth * xtext->CharHeight,
MEMF_CLEAR | MEMF_CHIP));
}
VOID AttachRemember(tokey, fromkey)
struct Remember **tokey, **fromkey;
/* Attach the contents of a Remember key to the allocations of another
* Remember key.
*/
{
struct Remember *workkey;
if ((workkey = *tokey) == NULL) *tokey = *fromkey;
else
{
while (workkey->NextRemember) workkey = workkey->NextRemember;
workkey->NextRemember = *fromkey;
}
*fromkey = NULL;
}
VOID MakeXTextFontData(font, style, bufptr, xtext)
struct TextFont *font;
USHORT style;
UBYTE *bufptr;
struct XTextSupport *xtext;
/* This awful little routine fills the buffer with the XText-style
* font imagery. The font is set to reflect the desired style, if any,
* and then one character at a time is drawn (using Text()) into
* a temporary rastport and then copies the character imagery into
* the XText buffer.
*/
{
SHORT i, i2;
UBYTE text;
SHORT baseline, height, xoffset, bytewidth;
SHORT extracolumn, movecolumn;
LONG enable;
UBYTE *ptr;
struct RastPort *rport;
struct BitMap *bmap;
struct TmpRas *tmpras;
struct Remember *localKey;
localKey = NULL;
rport = (struct RastPort *)AllocRemember(&localKey,
sizeof(struct RastPort), NULL);
bmap = (struct BitMap *)AllocRemember(&localKey,
sizeof(struct BitMap), NULL);
tmpras = (struct TmpRas *)AllocRemember(&localKey,
sizeof(struct TmpRas), NULL);
if ((rport == NULL) || (bmap == NULL) || (tmpras == NULL))
goto DONE;
bytewidth = xtext->MaxTextWidth;
height = xtext->CharHeight;
InitBitMap(bmap, 1, bytewidth * XTEXT_CHARWIDTH, height);
bmap->Planes[0] = xtext->NormalTextPlane;
InitRastPort(rport);
rport->BitMap = bmap;
rport->TmpRas = InitTmpRas(tmpras, xtext->InverseTextPlane,
bytewidth * height);
SetAPen(rport, 1);
SetBPen(rport, 0);
SetDrMd(rport, JAM2);
SetFont(rport, font);
enable = AskSoftStyle(rport);
SetSoftStyle(rport, style, enable);
baseline = rport->TxBaseline;
/* Now, italics are a real pain in the ascii.
* An 8-bit-wide font is normally wider than 8 bits when rendered
* in italics, so some of the character data must be lost.
* You can set the xoffset variable to some alternate value
* if you want an alternate slice of the font data.
*
* Furthermore, I just spent several hours discovering that
* the Text() routine creates the italics by shifting the lines above
* the baseline to the right *and* by shifting the lines below the
* baseline to the left. So what, you ask? Well, if a character
* is printed starting at column 0, in a RastPort
* unprotected by a Layer, then those left-shifted bits
* tickle the nose of the guru, doncha know. Achoo! Blink blink blink.
*/
xoffset = 0;
/* See the comment above regarding xoffset */
if (style & FSF_ITALIC) xoffset = ITALIC_LEFT_EDGE;
/* Text is drawn at least at column 8, and perhaps even further
* to the right if the left-shift of italics makes it necessary.
*/
extracolumn = ((height - baseline) - 1) >> 3;
movecolumn = (8 + (extracolumn << 3)) - xoffset;
for (i = 0; i < 256; i++)
{
text = i;
/* Finally, move the pens to our spot and draw the next character */
Move(rport, movecolumn, baseline);
Text(rport, &text, 1);
/* Now copy that character in XText font format into the buffer. */
ptr = bmap->Planes[0] + 1 + extracolumn;
for (i2 = 0; i2 < height; i2++)
{
*bufptr++ = *ptr;
if (FlagIsClear(xtext->Flags, SLIM_XTEXT)) *bufptr++ = 0;
ptr += bytewidth; /* Skip to the next row */
}
}
DONE:
FreeRemember(&localKey, TRUE);
}
/* *** MakeXTextFont() ******************************************************
*
* NAME
* MakeXTextFont -- Make font imagery for the XText routines
*
*
* SYNOPSIS
* UBYTE *MakeXTextFont(TextAttr, XTextSupport, Index);
*
*
* FUNCTION
* This routine creates font imagery in the format that the XText()
* routine uses. It allocates the font data buffer and then constructs
* the XText font imagery in this buffer using the imagery of the
* font specified by the TextAttr argument.
*
* This routine is normally called by MakeXTextSupport(). You do not
* need to use this routine unless you want to create fonts that
* have special styles such as bold, underline, and italics.
*
* If all is successful, this routine writes the address of the font
* data buffer in the XTextSupport's FontData array at the Index position,
* and returns the address of the new font data buffer.
* If anything goes wrong, the FontData array is unchanged and this
* routine returns NULL.
*
* You can specify font styles in your TextAttr structure.
* If the TextAttr argument is equal to NULL, the system's 80-column
* "topaz.font" will be used instead.
*
* You must have called MakeXTextSupport() before calling this routine,
* as this routine requires an initialized XTextSupport structure.
* All memory allocations are attached to the XTextSupport structure's
* Remember key.
*
*
* INPUTS
* TextAttr = a pointer to a TextAttr structure specifying the font
* to be used for this XText font imagery. If the TextAttr
* argument is equal to NULL, the system's 80-column "topaz.font"
* will be used.
*
* XTextSupport = a pointer to an initialized XTextSupport structure,
* which structure is created by a call to MakeXTextSupport().
*
* Index = index into the XTextSupport's FontData array for this font
*
*
* RESULT
* Returns a pointer to the memory block that contains the font imagery.
* If anything goes wrong (usually out of memory), returns NULL.
*
*
* EXAMPLE
* struct XTextSupport *xtext;
* struct TextAttr localTextAttr = { ... };
* xtext = MakeXTextSupport();
* [Make a BOLD font for XText() calls]
* localTextAttr.ta_Style = FSF_BOLD;
* MakeXTextFont(&localTextAttr, xtext, BOLD_FONT);
* [Write some BOLD characters]
* xtext->FontSelect = BOLD_FONT;
* XText(...);
*
* BUGS
* Well, if there is a bug it's a highly technical one that most
* of you can ignore. I'm not sure that it's entirely 100% for sure
* safe to work with DiskfontBase the way I have below and still expect
* this program to be re-entrant. It should be OK up to and including
* the 1.2 release of the system, but in the future this could cause
* some very mysterioso bug.
*
*
* SEE ALSO
* MakeXTextSupport(), XText(), UnmakeXTextSupport()
*/
UBYTE *MakeXTextFont(textattr, xtext, index)
struct TextAttr *textattr;
struct XTextSupport *xtext;
SHORT index;
/* === Get our special expanded-data font === */
{
struct TextFont *localfont;
BOOL openedlib, success;
UBYTE *data;
struct Remember *localkey;
SHORT size;
openedlib = success = FALSE;
localkey = NULL;
localfont = NULL;
/* If the user has specified no font, use 80-column "topaz.font" */
if (textattr == NULL) textattr = &DefaultXTextFont;
/* Allocate a special-character buffer where there are 256 characters
* and each character is CharHeight tall. If not SLIM_XTEXT, make the
* text two bytes wide for each character.
*/
size = 256 * xtext->CharHeight;
if (FlagIsClear(xtext->Flags, SLIM_XTEXT)) size *= 2;
if ((data = AllocRemember(&localkey, size, MEMF_CHIP)) == NULL)
goto DONE;
/* Attempt to open the specified font */
if ((localfont = OpenFont(textattr)) == NULL)
{
if ((DiskfontBase = (struct DiskfontBase *)
OpenLibrary("diskfont.library", 0)) == NULL)
goto DONE;
openedlib = TRUE;
if ((localfont = OpenDiskFont(textattr)) == NULL) goto DONE;
}
/* localfont is opened. Transform the data into XText format */
MakeXTextFontData(localfont, textattr->ta_Style, data, xtext);
CloseFont(localfont);
success = TRUE;
DONE:
if (openedlib) CloseLibrary(DiskfontBase);
if (success)
{
AttachRemember(&xtext->XTextKey, &localkey);
xtext->FontData[index] = data;
}
else
{
FreeRemember(&localkey, TRUE);
data = NULL;
}
return(data);
}
/* *** MakeXTextSupport() ***************************************************
*
* NAME
* MakeXTextSupport -- Allocate and initialize XText Support data
*
*
* SYNOPSIS
* struct XTextSupport *MakeXTextSupport(RastPort, TextAttr,
* MaxTextWidth, InitialFlags);
*
*
* FUNCTION
* This routine allocates an XTextSupport structure and initializes
* the structure for use by the XText routines.
*
* The font specified by the TextAttr argument is opened. If the
* TextAttr arg is equal to NULL, the system font "topaz.font" is
* opened instead. If you are specifying a TextAttr, the font you
* specify must have a character cel that is 8-bits wide.
*
* Image data from this font is then used to create the special
* font data used by the XText routines. The address of this data
* is put in the FontData variable of the XTextSupport structure,
* as well as in all of the elements in the SpecialFontData array.
*
* The MaxTextWidth argument describes the maximum number of
* characters that you will ever print at one time with the
* XText() routine. Typically this number will be 80 or 40,
* depending on whether your display is high-res or low-res.
* This number should be an even number; if the number you
* supply is odd, the actual number used will be your number
* rounded up to the next even number.
*
* The InitialFlags argument is used to preset your XTextSupport's
* Flags variable before anything is done with the structure.
* See the file xtext.h for the definitions of the XTextSupport
* structure's Flags.
*
* An InitialFlag of note is the SLIM_XTEXT flag, which you can
* set to define that you want the slim (and slow) XText technique
* to be used when the XText font data is created and when
* XText is rendered to the display. The advantage of SLIM_XTEXT
* is that the technique requires half as much memory as the
* fast fat technique. The disadvantage is that it runs about
* 20% more slowly than fast fat XText.
*
* After you have called MakeXTextSupport(), you can use
* the Remember key in the XTextSupport structure -- named
* XTextKey -- for further memory allocations. All memory
* allocations made using XTextKey are freed when
* UnmakeXTextSupport() is called.
*
*
* INPUTS
* RastPort = a pointer to the RastPort that will be the destination
* for text created by the XText routines. Typically, this
* will be the RastPort of an Intuition window or screen
* that you've opened. For an example, see EXAMPLE below.
*
* TextAttr = a pointer to a TextAttr structure specifying the font
* to be used for this XText font imagery. If the TextAttr
* argument is equal to NULL, the system's 80-column "topaz.font"
* will be used.
*
* MaxTextWidth = Maximum number of characters per line. This should
* be an even number, and if odd will be rounded up to the
* next even number.
*
* InitialFlags = Flags that will be preset in your XTextSupport's
* Flags variable before anything is done with the structure.
* See the file xtext.h for the definitions of the XTextSupport
* structure's Flags.
*
*
* RESULT
* Returns the address of the XTextSupport structure, or NULL
* if there were any problems (usually out of memory).
*
*
* EXAMPLE
* window = OpenWindow( ... );
* xtext = MakeXTextSupport(window->RPort, &DiskFontTextAttr, 80, NULL);
* - or, as another example, open a 320 screen and ... -
* screen = OpenScreen( ... );
* xtext = MakeXTextSupport(&screen->RastPort, NULL, 40, SLIM_XTEXT);
*
*
* SEE ALSO
* MakeXTextFont(), XText(), UnmakeXTextSupport()
*/
struct XTextSupport *MakeXTextSupport(rport, textattr, maxwidth, flags)
struct RastPort *rport;
struct TextAttr *textattr;
SHORT maxwidth;
SHORT flags;
{
struct XTextSupport *xtext;
SHORT i;
maxwidth = (maxwidth + 1) & -2;
if ((xtext = (struct XTextSupport *)AllocMem(sizeof(struct XTextSupport),
MEMF_CLEAR)) == NULL)
return (NULL);
xtext->FrontPen = 1;
xtext->DrawMode = JAM2;
xtext->MaxTextWidth = maxwidth;
xtext->Flags = flags;
/* If the user has specified no font, use 80-column "topaz.font" */
if (textattr == NULL) textattr = &DefaultXTextFont;
xtext->CharHeight = textattr->ta_YSize;
xtext->NormalTextPlane = AllocXTextPlane(xtext);
xtext->InverseTextPlane = AllocXTextPlane(xtext);
xtext->AllClearPlane = AllocXTextPlane(xtext);
xtext->AllSetPlane = AllocXTextPlane(xtext);
if ((xtext->NormalTextPlane == NULL)
|| (xtext->InverseTextPlane == NULL)
|| (xtext->AllClearPlane == NULL)
|| (xtext->AllSetPlane == NULL))
{
UnmakeXTextSupport(xtext);
return (NULL);
}
for (i = 0; i < (xtext->CharHeight * maxwidth); i++)
xtext->AllSetPlane[i] = -1;
xtext->OutputRPort = rport;
InitBitMap(&xtext->TextBitMap, rport->BitMap->Depth,
maxwidth * XTEXT_CHARWIDTH, xtext->CharHeight);
if (MakeXTextFont(textattr, xtext, NORMAL_FONT) == NULL)
{
UnmakeXTextSupport(xtext);
return (NULL);
}
for (i = 1; i < 8; i++)
xtext->FontData[i] = xtext->FontData[0];
return(xtext);
}
/* *** UnmakeXTextSupport() *************************************************
*
* NAME
* UnmakeXTextSupport -- Free the XTextSupport structure and buffers
*
*
* SYNOPSIS
* UnmakeXTextSupport(XTextSupport)
*
*
* FUNCTION
* Frees the XTextSupport structure and buffers.
*
*
* INPUTS
* XTextSupport = pointer to an XTextSupport structure (typically
* created by a call to MakeXTextSupport() )
*
*
* RESULT
* None
*
*
* SEE ALSO
* MakeXTextSupport()
*/
VOID UnmakeXTextSupport(xtext)
struct XTextSupport *xtext;
{
if (xtext)
{
FreeRemember(&xtext->XTextKey, TRUE);
FreeMem(xtext, sizeof(struct XTextSupport));
}
}