BigEasy/BigEasyTextish.c

/*
                File:       BigEasyTextish.c
            
                Contains:   xxx put contents here xxx
            
                Written by: xxx put writers here xxx
            
                Copyright:  © 1990-1992 by Apple Computer, Inc., all rights reserved.
            
    This file is used in these builds: Warhol
 
                Change History (most recent first):
            
        <9+>      5/6/93    dvb     String->Number
         <9>      1/7/93    dvb     New functions (TruncateString).
         <8>     1/20/92    dvb     This kind of FixMath is KRAZEE!
         <7>    11/12/91    dvb     General fixation
         <6>     11/4/91    JB      Use fixmath instead of floats
         <5>      6/3/91    dvb     Just Hackin'.
         <4>     5/23/91    PH      THINK C 5
         <3>     4/25/91    JB      Changing to new THINK_C interface files
         <2>    11/16/90    dvb     Remove drawcstring
        <1>     11/16/90    dvb     Check In! Fresh after Camplejohn Soup!
            
                To Do:
            */
 
/* file: BigEasyTextish.c
 *
 * Started 13 July 1989, more or less.
 *
 * A set of routines for converting and
 * displaying textish things on the Mac.
 *
 */
 
 
 
/************************************
* Inclusions
************************************/
 
#define BigEasyTextish
 
#include <QuickDraw.h>
#include <Packages.h>
#include <Memory.h>
#include <FixMath.h>
 
#include "BigEasyTextish.h"
 
 
/************************************
* Limits
************************************/
 
/************************************
* Types and globals
************************************/
static char dHexChars[] = "0123456789ABCDEF";
 
/************************************
* Routines
************************************/
void AnyBaseToPString(long n,short b,short g,StringPtr c)
/*
  * Convert 32 bit number n to
  *  string c, in number base b.
  * g is the format: 0 - any length signed
  * positive: unsigned with leading zeros
  * to width g.
  */
    {
    register short charCount;
    register StringPtr w;
    register unsigned long x;       /* unsigned number for divs */
 
    if(b<2 || b>16)             /* a ridiculous number base?    */
        {
        c[0] = 0;               /* mark as empty string     */
        return;             /* bye.                 */
        }
 
    if(g == 0)
        {
        charCount = 1;          /* initially, 1 char long       */
 
        if(n < 0)               /* number negative?     */
            {
            charCount++;        /* one more char            */
            n = -n;             /* make it positive         */
            c[1] = '-';         /* drop in a minus sign     */
            if(n < 0)
                n --;           /* most negative? pin it. */
            }
 
        x = n;              /* find out how many digits */
        while(x /= b)
            charCount++;
 
        c[0] = charCount;       /* number of digits, plus sign  */
        w = c+c[0];         /* we'll walk backwards     */
        x = n;
        do
            {
            *w-- = dHexChars[x%b];
            x /= b;
            } while(x);
        }
    else if(g > 0)
        {                   /* leading zero format      */
        c[0] = g;           /* poke in number of chars  */
        x = n;              /* get our number unsigned  */
        w = &c[g];          /* point to end of string       */
 
        while(g--)
            {
            *w-- = dHexChars[x%b];
            x /= b;
            }
        }
    else if(g < 0)
        {                   /* leading space format   */
        g = -g;
        c[0] = g;               /* poke in number of chars  */
        x = n;              /* get our number unsigned  */
        w = &c[g];          /* point to end of string       */
        
        while(g--)
            {
            *w-- = dHexChars[x%b];
            x /= b;
            }
        g = c[0]-1;
        w = &c[1];
        while(g--)
            {
            if (*w == '0')
                *w++ = 0xca;
            else
                break;
            }
        }
    else                    /* negative format passed   */
        c[0] = 0;
    }
 
void DrawNum(n)
/*
  * Draw number n as a signed long, in decimal
  */
    long n;
    {
    Str31 c;
 
    AnyBaseToPString(n,10,0,c);
    DrawString((StringPtr)c);
    }
 
long dTens[] =
    {
    1,
    10,
    100,
    1000,
    10000,
    100000,
    1000000,
    10000000,
    100000000,
    1000000000
    };
 
 
void FixedPointToPString(long n,short g,short p,StringPtr s)
/*
  * Draw number n in fixed point, with
  * g decimal places, with p fractional
  * binary places.
  */
    {
    Str31 c;
    long x;     /* This should float to avoid overflows, but JB says, No! */
 
    s[0] = 0;
 
    if( n < 0 )
        {
        ConcatenatePStrings(s,"\p-");
        n = -n;
        if(n < 0)
            n--;        /* pin most negative */
        }
 
    AnyBaseToPString(n>>p,10,0,c);
    ConcatenatePStrings(s,c);
    ConcatenatePStrings(s,"\p.");
 
    if(g>9)
        g = 9;
 
    if(g)
        {
        x = (n & ((1L<<p)-1) );
        x *= dTens[g];
        x /= (x,1L<<p);
 
        AnyBaseToPString(x,10,g,c);
        ConcatenatePStrings(s,c);
        }
    }
 
 
void PStringToFixedPoint(StringPtr s,short g,short p,long *n)
    {
    long x;
    unsigned long y,z,z10;
    short count;
    Boolean decimal;
    Boolean sign;
 
    count = *s++;
    x = 0;
 
    decimal = false;
    sign = false;
 
    z = (1L<<p);
    z10 = 10;
 
    while(count-- && z)
        {
        y = *s;
        if(y == '.')
            decimal = true;
        else if (y == '-')
            sign = true;
        else
            {
            y = y - '0';
            if(y < 10)
                {
                if(!decimal)
                    {
                    x *= 10;
                    x += y << p;
                    }
                else
                    {
                    x += (y * z + z10/2) / z10;
                    z10 *= 10;
                    }
                }
            }
        s++;
        }
 
    if(sign)
        x = -x;
 
    *n = x;
    }
 
void DrawFixedPoint(long n,short g,short p)
/*
  * Draw number n in fixed point, with
  * g decimal places, with p fractional
  * binary places.
  */
    {
    Str255 s;
 
    FixedPointToPString(n,g,p,s);
    DrawString(s);
    }
 
 
void DrawFixed(long n,short g)
/*
  * Draw number n in fixed point, with
  * g decimal places.
  */
    {
    DrawFixedPoint(n,g,16);
    }
 
void DrawFixedPointJustified(long n,short g,short p,short h)
/*
  * Draw number n in fixed point, with
  * g decimal places, with p fractional
  * binary places.
  */
    {
    Str255 s;
    Str31 c;
    long x;
 
    s[0] = 0;
 
    if( n < 0 )
        {
        ConcatenatePStrings(s,"\p-");
        n = -n;
        if(n < 0)
            n --;           /* most negative? pin it. */
        }
 
    AnyBaseToPString(n>>p,10,-h,c);
    ConcatenatePStrings(s,c);
    ConcatenatePStrings(s,"\p.");
 
    if(g>9)
        g = 9;
 
    if(g)
        {
        
        x = (n & ((1L<<p)-1) );
        x *= dTens[g];
        x /= (x,1L<<p);
 
        AnyBaseToPString(x,10,g,c);
        ConcatenatePStrings(s,c);
        }
 
    DrawString(s);
    }
 
 
void DrawFixedJustified(long n,short g,short h)
/*
  * Draw number n in fixed point, with
  * g decimal places.
  */
    {
    DrawFixedPointJustified(n,g,16,h);
    }
 
 
 
void DrawFrac(long n,short g)
/*
  * Draw number n as a frac (2.30), with
  * g decimal places.
  */
    {
    DrawFixedPoint(n,g,30);
    }
 
void DrawHexLong(unsigned long n)
/*
  * Draw an 8-digit hex number
  * with leading zeroes
  */
    {
    Str31 c;
 
    AnyBaseToPString(n,16,8,c);
    DrawString((StringPtr)c);
    }
 
void DrawHexShort( unsigned short n)
/*
  * Draw a 4-digit hex number
  * with leading zeroes
  */
    {
    Str31 c;
 
    AnyBaseToPString(n,16,4,c);
    DrawString(c);
    }
 
void DrawHexByte(unsigned char n)
    {
    Str31 c;
 
    AnyBaseToPString(n,16,2,c);
    DrawString(c);
    }
 
void CToPString(register char *c,register StringPtr p)
    {
    register short i;
    register StringPtr pWalker;
 
    i = 0;
    pWalker = p+1;
    while(*pWalker++ = *c++)
        i++;
    *p = i;
    }
 
void DrawCR(void)
/*
  * Bump penposition down a line, to
  * gLeftMargin, and +gLineHeight.
  */
    {
    Point p;
 
    GetPen(&p);
    p.h = gLeftMargin;
    p.v += gLineHeight;
    MoveTo(p.h,p.v);
    }
 
 
 
short CStringWidth(char *c)
/*
  * Do a StringWidth on a C string
  */
    {
    Str255 p;
 
    CToPString(c,p);
    return StringWidth((StringPtr)p);
    }
 
 
void CopyPString(StringPtr dest,StringPtr src)
    {
    if(dest && src)
        BlockMove(src,dest,(*src) + 1);
    }
 
 
void ConcatenatePStrings(StringPtr dest,StringPtr src)
    {
    BlockMove(src+1,dest+1+(*dest),*src);
    *dest += *src;
    }
 
 
void DrawStringRight(StringPtr s)
/*
 * Draw the string from the current pen position
 * off to the left; leave the pen where it started.
 */
    {
    Point po;
 
    GetPen(&po);
    Move(-StringWidth(s),0);
    DrawString(s);
    }
 
void DrawStringCenter(StringPtr s)
/*
 * Draw the string centered at
 * the current pen position; 
 * leave the pen where it started.
 */
    {
    Point po;
 
    GetPen(&po);
    Move(-StringWidth(s)/2,0);
    DrawString(s);
    MoveTo(po.h,po.v);
    }
 
void DrawStringLeft(StringPtr s)
/*
 * Draw the string from the current pen position
 * off to the right; leave the pen where it started.
 */
    {
    Point po;
 
    GetPen(&po);
    DrawString(s);
    MoveTo(po.h,po.v);
    }
 
 
void TruncateString(StringPtr s, short width)
/*
 * Draw the string limited to the width passed,
 * Truncated if necessary with a trailing ÒÉÓ.
 */
    {
    while(StringWidth(s) > width)
        {
        s[0] --;
        s[s[0]] = 'É';
        }
    }
 
 
void DrawStringTruncated(StringPtr s, short width)
/*
 * Draw the string limited to the width passed,
 * Truncated if necessary with a trailing ÒÉÓ.
 */
    {
    Str255 s2;
 
    CopyPString(s2,s);
    TruncateString(s2,  width);
    DrawString(s2);
    }
 
 
 
void OSTypeToString(StringPtr dest,OSType x)
    {
    dest[0] = 4;
    dest[1] = (x>>24);
    dest[2] = (x>>16);
    dest[3] = (x>>8);
    dest[4] = x;
    }