home *** CD-ROM | disk | FTP | other *** search
-
- /* *** 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));
- }
- }
-
-
-