home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 073.lha / XText / xtextsup.c < prev   
C/C++ Source or Header  |  1987-06-02  |  16KB  |  500 lines

  1.  
  2. /* *** xtextsup.c ***********************************************************
  3.  *
  4.  * XText  --  Support Procedures
  5.  *    from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Created for Amiga developers.
  11.  * Any or all of this code can be used in any program as long as this
  12.  * entire notice is retained, ok?  Thanks.
  13.  *
  14.  * HISTORY       NAME            DESCRIPTION
  15.  * -----------   --------------  --------------------------------------------
  16.  * 27 Oct 86     RJ              Add XText buffer stuff, prepare for release
  17.  * March 86      RJ              Incorporated this code in Sidecar
  18.  * 26 Jan 86     RJ Mical        Created this file (on my birthday!)
  19.  *
  20.  * *********************************************************************** */
  21.  
  22.  
  23. #include "xtext.h"
  24.  
  25.  
  26. VOID UnmakeXTextSupport();
  27.  
  28.  
  29. struct TextAttr DefaultXTextFont =
  30.       {
  31.       (UBYTE *)"topaz.font",
  32.       TOPAZ_EIGHTY,
  33.       0,
  34.       FS_NORMAL
  35.       };
  36.  
  37.  
  38. UBYTE *AllocXTextPlane(xtext)
  39. struct XTextSupport *xtext;
  40. /* This routine allocates an XText text plane, with one byte for each
  41.  * line of each character in the widest allowable line.
  42.  */
  43. {
  44.    return (AllocRemember(&xtext->XTextKey, 
  45.          xtext->MaxTextWidth * xtext->CharHeight,
  46.          MEMF_CLEAR | MEMF_CHIP));
  47. }
  48.  
  49.  
  50.  
  51. VOID AttachRemember(tokey, fromkey)
  52. struct Remember **tokey, **fromkey;
  53. /* Attach the contents of a Remember key to the allocations of another
  54.  * Remember key.
  55.  */
  56. {
  57.    struct Remember *workkey;
  58.  
  59.    if ((workkey = *tokey) == NULL) *tokey = *fromkey;
  60.    else
  61.       {
  62.       while (workkey->NextRemember) workkey = workkey->NextRemember;
  63.       workkey->NextRemember = *fromkey;
  64.       }
  65.    *fromkey = NULL;
  66. }
  67.  
  68.  
  69.  
  70. VOID MakeXTextFontData(font, style, bufptr, xtext)
  71. struct TextFont *font;
  72. USHORT style;
  73. UBYTE *bufptr;
  74. struct XTextSupport *xtext;
  75. /* This awful little routine fills the buffer with the XText-style
  76.  * font imagery.  The font is set to reflect the desired style, if any,
  77.  * and then one character at a time is drawn (using Text()) into
  78.  * a temporary rastport and then copies the character imagery into
  79.  * the XText buffer.
  80.  */
  81. {
  82.    SHORT i, i2;
  83.    UBYTE text;
  84.    SHORT baseline, height, xoffset, bytewidth;
  85.    SHORT extracolumn, movecolumn;
  86.    LONG enable;
  87.    UBYTE *ptr;
  88.    struct RastPort *rport;
  89.    struct BitMap *bmap;
  90.    struct TmpRas *tmpras;
  91.    struct Remember *localKey;
  92.  
  93.    localKey = NULL;
  94.    rport = (struct RastPort *)AllocRemember(&localKey,
  95.          sizeof(struct RastPort), NULL);
  96.    bmap = (struct BitMap *)AllocRemember(&localKey,
  97.          sizeof(struct BitMap), NULL);
  98.    tmpras = (struct TmpRas *)AllocRemember(&localKey,
  99.          sizeof(struct TmpRas), NULL);
  100.    if ((rport == NULL) || (bmap == NULL) || (tmpras == NULL))
  101.       goto DONE;
  102.  
  103.    bytewidth = xtext->MaxTextWidth;
  104.    height = xtext->CharHeight;
  105.  
  106.    InitBitMap(bmap, 1, bytewidth * XTEXT_CHARWIDTH, height);
  107.    bmap->Planes[0] = xtext->NormalTextPlane;
  108.    InitRastPort(rport);
  109.    rport->BitMap = bmap;
  110.    rport->TmpRas = InitTmpRas(tmpras, xtext->InverseTextPlane,
  111.          bytewidth * height);
  112.  
  113.    SetAPen(rport, 1);
  114.    SetBPen(rport, 0);
  115.    SetDrMd(rport, JAM2);
  116.  
  117.    SetFont(rport, font);
  118.    enable = AskSoftStyle(rport);
  119.    SetSoftStyle(rport, style, enable);
  120.  
  121.    baseline = rport->TxBaseline;
  122.  
  123.    /* Now, italics are a real pain in the ascii.
  124.     * An 8-bit-wide font is normally wider than 8 bits when rendered 
  125.     * in italics, so some of the character data must be lost.  
  126.     * You can set the xoffset variable to some alternate value 
  127.     * if you want an alternate slice of the font data.
  128.     * 
  129.     * Furthermore, I just spent several hours discovering that 
  130.     * the Text() routine creates the italics by shifting the lines above
  131.     * the baseline to the right *and* by shifting the lines below the
  132.     * baseline to the left.  So what, you ask?  Well, if a character 
  133.     * is printed starting at column 0, in a RastPort 
  134.     * unprotected by a Layer, then those left-shifted bits 
  135.     * tickle the nose of the guru, doncha know.  Achoo!  Blink blink blink.
  136.     */
  137.  
  138.    xoffset = 0;
  139.    /* See the comment above regarding xoffset */
  140.    if (style & FSF_ITALIC) xoffset = ITALIC_LEFT_EDGE;
  141.  
  142.    /* Text is drawn at least at column 8, and perhaps even further 
  143.     * to the right if the left-shift of italics makes it necessary.
  144.     */
  145.    extracolumn = ((height - baseline) - 1) >> 3;
  146.    movecolumn = (8 + (extracolumn << 3)) - xoffset;
  147.  
  148.    for (i = 0; i < 256; i++)
  149.       {
  150.       text = i;
  151.  
  152.       /* Finally, move the pens to our spot and draw the next character */
  153.       Move(rport, movecolumn, baseline);
  154.       Text(rport, &text, 1);
  155.  
  156.       /* Now copy that character in XText font format into the buffer. */
  157.       ptr = bmap->Planes[0] + 1 + extracolumn;
  158.       for (i2 = 0; i2 < height; i2++)
  159.          {
  160.          *bufptr++ = *ptr;
  161.          if (FlagIsClear(xtext->Flags, SLIM_XTEXT)) *bufptr++ = 0;
  162.          ptr += bytewidth;    /* Skip to the next row */
  163.          }
  164.       }
  165.  
  166. DONE:
  167.    FreeRemember(&localKey, TRUE);
  168. }
  169.  
  170.  
  171.  
  172. /* *** MakeXTextFont() ******************************************************
  173.  * 
  174.  * NAME
  175.  *    MakeXTextFont  --  Make font imagery for the XText routines
  176.  * 
  177.  * 
  178.  * SYNOPSIS
  179.  *    UBYTE *MakeXTextFont(TextAttr, XTextSupport, Index);
  180.  * 
  181.  * 
  182.  * FUNCTION
  183.  *    This routine creates font imagery in the format that the XText()
  184.  *    routine uses.  It allocates the font data buffer and then constructs
  185.  *    the XText font imagery in this buffer using the imagery of the
  186.  *    font specified by the TextAttr argument.
  187.  *    
  188.  *    This routine is normally called by MakeXTextSupport().  You do not
  189.  *    need to use this routine unless you want to create fonts that
  190.  *    have special styles such as bold, underline, and italics.
  191.  *    
  192.  *    If all is successful, this routine writes the address of the font 
  193.  *    data buffer in the XTextSupport's FontData array at the Index position,
  194.  *    and returns the address of the new font data buffer.  
  195.  *    If anything goes wrong, the FontData array is unchanged and this 
  196.  *    routine returns NULL.
  197.  *    
  198.  *    You can specify font styles in your TextAttr structure.
  199.  *    If the TextAttr argument is equal to NULL, the system's 80-column 
  200.  *    "topaz.font" will be used instead.
  201.  *    
  202.  *    You must have called MakeXTextSupport() before calling this routine,
  203.  *    as this routine requires an initialized XTextSupport structure.
  204.  *    All memory allocations are attached to the XTextSupport structure's
  205.  *    Remember key.
  206.  *    
  207.  *    
  208.  * INPUTS
  209.  *    TextAttr = a pointer to a TextAttr structure specifying the font
  210.  *       to be used for this XText font imagery.  If the TextAttr
  211.  *       argument is equal to NULL, the system's 80-column "topaz.font"
  212.  *       will be used.
  213.  *    
  214.  *    XTextSupport = a pointer to an initialized XTextSupport structure,
  215.  *       which structure is created by a call to MakeXTextSupport().
  216.  *    
  217.  *    Index = index into the XTextSupport's FontData array for this font
  218.  *    
  219.  *    
  220.  * RESULT
  221.  *    Returns a pointer to the memory block that contains the font imagery.
  222.  *    If anything goes wrong (usually out of memory), returns NULL.
  223.  *    
  224.  *    
  225.  * EXAMPLE
  226.  *      struct XTextSupport *xtext;
  227.  *      struct TextAttr localTextAttr = { ... };
  228.  *      xtext = MakeXTextSupport();
  229.  *    [Make a BOLD font for XText() calls]
  230.  *      localTextAttr.ta_Style = FSF_BOLD;
  231.  *      MakeXTextFont(&localTextAttr, xtext, BOLD_FONT);
  232.  *    [Write some BOLD characters]
  233.  *      xtext->FontSelect = BOLD_FONT;
  234.  *      XText(...);
  235.  *
  236.  * BUGS
  237.  *    Well, if there is a bug it's a highly technical one that most
  238.  *    of you can ignore.  I'm not sure that it's entirely 100% for sure 
  239.  *    safe to work with DiskfontBase the way I have below and still expect
  240.  *    this program to be re-entrant.  It should be OK up to and including 
  241.  *    the 1.2 release of the system, but in the future this could cause
  242.  *    some very mysterioso bug.
  243.  *    
  244.  *    
  245.  * SEE ALSO
  246.  *    MakeXTextSupport(), XText(), UnmakeXTextSupport()
  247.  */
  248. UBYTE *MakeXTextFont(textattr, xtext, index)
  249. struct TextAttr *textattr;
  250. struct XTextSupport *xtext;
  251. SHORT index;
  252. /* === Get our special expanded-data font === */
  253. {
  254.    struct TextFont *localfont;
  255.    BOOL openedlib, success;
  256.    UBYTE *data;
  257.    struct Remember *localkey;
  258.    SHORT size;
  259.  
  260.    openedlib = success = FALSE;
  261.    localkey = NULL;
  262.    localfont = NULL;
  263.  
  264.    /* If the user has specified no font, use 80-column "topaz.font" */
  265.    if (textattr == NULL) textattr = &DefaultXTextFont;
  266.  
  267.    /* Allocate a special-character buffer where there are 256 characters
  268.     * and each character is CharHeight tall.  If not SLIM_XTEXT, make the 
  269.     * text two bytes wide for each character.
  270.     */
  271.    size = 256 * xtext->CharHeight;
  272.    if (FlagIsClear(xtext->Flags, SLIM_XTEXT)) size *= 2;
  273.    if ((data = AllocRemember(&localkey, size, MEMF_CHIP)) == NULL)
  274.       goto DONE;
  275.  
  276.    /* Attempt to open the specified font */
  277.    if ((localfont = OpenFont(textattr)) == NULL)
  278.       {
  279.       if ((DiskfontBase = (struct DiskfontBase *)
  280.             OpenLibrary("diskfont.library", 0)) == NULL)
  281.          goto DONE;
  282.       openedlib = TRUE;
  283.  
  284.       if ((localfont = OpenDiskFont(textattr)) == NULL) goto DONE;
  285.       }
  286.  
  287.    /* localfont is opened.  Transform the data into XText format */
  288.    MakeXTextFontData(localfont, textattr->ta_Style, data, xtext);
  289.  
  290.    CloseFont(localfont);
  291.  
  292.    success = TRUE;
  293.  
  294. DONE:
  295.    if (openedlib) CloseLibrary(DiskfontBase);
  296.    if (success)
  297.       {
  298.       AttachRemember(&xtext->XTextKey, &localkey);
  299.       xtext->FontData[index] = data;
  300.       }
  301.    else 
  302.       {
  303.       FreeRemember(&localkey, TRUE);
  304.       data = NULL;
  305.       }
  306.  
  307.    return(data);
  308. }
  309.  
  310.  
  311.  
  312. /* *** MakeXTextSupport() ***************************************************
  313.  * 
  314.  * NAME
  315.  *    MakeXTextSupport  --  Allocate and initialize XText Support data
  316.  * 
  317.  * 
  318.  * SYNOPSIS
  319.  *    struct XTextSupport *MakeXTextSupport(RastPort, TextAttr, 
  320.  *          MaxTextWidth, InitialFlags);
  321.  * 
  322.  * 
  323.  * FUNCTION
  324.  *    This routine allocates an XTextSupport structure and initializes
  325.  *    the structure for use by the XText routines.
  326.  * 
  327.  *    The font specified by the TextAttr argument is opened.  If the
  328.  *    TextAttr arg is equal to NULL, the system font "topaz.font" is
  329.  *    opened instead.  If you are specifying a TextAttr, the font you
  330.  *    specify must have a character cel that is 8-bits wide.
  331.  * 
  332.  *    Image data from this font is then used to create the special
  333.  *    font data used by the XText routines.  The address of this data
  334.  *    is put in the FontData variable of the XTextSupport structure,
  335.  *    as well as in all of the elements in the SpecialFontData array.
  336.  * 
  337.  *    The MaxTextWidth argument describes the maximum number of 
  338.  *    characters that you will ever print at one time with the 
  339.  *    XText() routine.  Typically this number will be 80 or 40, 
  340.  *    depending on whether your display is high-res or low-res.  
  341.  *    This number should be an even number; if the number you 
  342.  *    supply is odd, the actual number used will be your number 
  343.  *    rounded up to the next even number.
  344.  * 
  345.  *    The InitialFlags argument is used to preset your XTextSupport's
  346.  *    Flags variable before anything is done with the structure.  
  347.  *    See the file xtext.h for the definitions of the XTextSupport 
  348.  *    structure's Flags.
  349.  * 
  350.  *    An InitialFlag of note is the SLIM_XTEXT flag, which you can 
  351.  *    set to define that you want the slim (and slow) XText technique 
  352.  *    to be used when the XText font data is created and when 
  353.  *    XText is rendered to the display.  The advantage of SLIM_XTEXT 
  354.  *    is that the technique requires half as much memory as the 
  355.  *    fast fat technique.  The disadvantage is that it runs about 
  356.  *    20% more slowly than fast fat XText.  
  357.  * 
  358.  *    After you have called MakeXTextSupport(), you can use
  359.  *    the Remember key in the XTextSupport structure -- named
  360.  *    XTextKey -- for further memory allocations.  All memory
  361.  *    allocations made using XTextKey are freed when 
  362.  *    UnmakeXTextSupport() is called.
  363.  * 
  364.  * 
  365.  * INPUTS
  366.  *    RastPort = a pointer to the RastPort that will be the destination
  367.  *       for text created by the XText routines.  Typically, this
  368.  *       will be the RastPort of an Intuition window or screen
  369.  *       that you've opened.  For an example, see EXAMPLE below.
  370.  * 
  371.  *    TextAttr = a pointer to a TextAttr structure specifying the font
  372.  *       to be used for this XText font imagery.  If the TextAttr
  373.  *       argument is equal to NULL, the system's 80-column "topaz.font"
  374.  *       will be used.
  375.  * 
  376.  *    MaxTextWidth = Maximum number of characters per line.  This should 
  377.  *       be an even number, and if odd will be rounded up to the 
  378.  *       next even number.
  379.  * 
  380.  *    InitialFlags = Flags that will be preset in your XTextSupport's
  381.  *       Flags variable before anything is done with the structure.  
  382.  *       See the file xtext.h for the definitions of the XTextSupport 
  383.  *       structure's Flags.
  384.  * 
  385.  * 
  386.  * RESULT
  387.  *    Returns the address of the XTextSupport structure, or NULL
  388.  *    if there were any problems (usually out of memory).
  389.  * 
  390.  * 
  391.  * EXAMPLE
  392.  *    window = OpenWindow( ... );
  393.  *    xtext = MakeXTextSupport(window->RPort, &DiskFontTextAttr, 80, NULL);
  394.  *    - or, as another example, open a 320 screen and ... -
  395.  *    screen = OpenScreen( ... );
  396.  *    xtext = MakeXTextSupport(&screen->RastPort, NULL, 40, SLIM_XTEXT);
  397.  * 
  398.  * 
  399.  * SEE ALSO
  400.  *    MakeXTextFont(), XText(), UnmakeXTextSupport()
  401.  */
  402. struct XTextSupport *MakeXTextSupport(rport, textattr, maxwidth, flags)
  403. struct RastPort *rport;
  404. struct TextAttr *textattr;
  405. SHORT maxwidth;
  406. SHORT flags;
  407. {
  408.    struct XTextSupport *xtext;
  409.    SHORT i;
  410.  
  411.    maxwidth = (maxwidth + 1) & -2;
  412.  
  413.    if ((xtext = (struct XTextSupport *)AllocMem(sizeof(struct XTextSupport),
  414.          MEMF_CLEAR)) == NULL)
  415.       return (NULL);
  416.  
  417.    xtext->FrontPen = 1;
  418.    xtext->DrawMode = JAM2;
  419.    xtext->MaxTextWidth = maxwidth;
  420.    xtext->Flags = flags;
  421.  
  422.    /* If the user has specified no font, use 80-column "topaz.font" */
  423.    if (textattr == NULL) textattr = &DefaultXTextFont;
  424.  
  425.    xtext->CharHeight = textattr->ta_YSize;
  426.  
  427.    xtext->NormalTextPlane = AllocXTextPlane(xtext);
  428.    xtext->InverseTextPlane = AllocXTextPlane(xtext);
  429.    xtext->AllClearPlane = AllocXTextPlane(xtext);
  430.    xtext->AllSetPlane = AllocXTextPlane(xtext);
  431.  
  432.    if ((xtext->NormalTextPlane == NULL)
  433.          || (xtext->InverseTextPlane == NULL)
  434.          || (xtext->AllClearPlane == NULL)
  435.          || (xtext->AllSetPlane == NULL))
  436.       {
  437.       UnmakeXTextSupport(xtext);
  438.       return (NULL);
  439.       }
  440.  
  441.    for (i = 0; i < (xtext->CharHeight * maxwidth); i++)
  442.       xtext->AllSetPlane[i] = -1;
  443.  
  444.    xtext->OutputRPort = rport;
  445.  
  446.    InitBitMap(&xtext->TextBitMap, rport->BitMap->Depth, 
  447.          maxwidth * XTEXT_CHARWIDTH, xtext->CharHeight);
  448.  
  449.    if (MakeXTextFont(textattr, xtext, NORMAL_FONT) == NULL)
  450.       {
  451.       UnmakeXTextSupport(xtext);
  452.       return (NULL);
  453.       }
  454.  
  455.    for (i = 1; i < 8; i++)
  456.       xtext->FontData[i] = xtext->FontData[0];
  457.  
  458.    return(xtext);
  459. }
  460.  
  461.  
  462.  
  463. /* *** UnmakeXTextSupport() *************************************************
  464.  * 
  465.  * NAME
  466.  *    UnmakeXTextSupport  --  Free the XTextSupport structure and buffers
  467.  * 
  468.  * 
  469.  * SYNOPSIS
  470.  *    UnmakeXTextSupport(XTextSupport)
  471.  * 
  472.  * 
  473.  * FUNCTION
  474.  *    Frees the XTextSupport structure and buffers.
  475.  *
  476.  *
  477.  * INPUTS
  478.  *    XTextSupport = pointer to an XTextSupport structure (typically
  479.  *               created by a call to MakeXTextSupport() )
  480.  *
  481.  *
  482.  * RESULT
  483.  *    None
  484.  *
  485.  *
  486.  * SEE ALSO
  487.  *    MakeXTextSupport()
  488.  */
  489. VOID UnmakeXTextSupport(xtext)
  490. struct XTextSupport *xtext;
  491. {
  492.    if (xtext)
  493.       {
  494.       FreeRemember(&xtext->XTextKey, TRUE);
  495.       FreeMem(xtext, sizeof(struct XTextSupport));
  496.       }
  497. }
  498.  
  499.  
  500.