/*
 * FSM/SpeedoGDOS  gdos bindings
 * this file has some relationship to a file supplied by Atari
 * but it changed quite a bit (among other things it appears to work).
 * v_shtext survived verbatim from the original.
 *
 * ++jrb add more speedoGDOS stuff. now it looks nothing like the one
 *       from atari. i guess this file should now be called vdispeedo or
 *       something like that. btw: atari claims that the api did'nt change
 *       yeah right!
 */

#include "common.h"
#ifndef _COMPILER_H
# include <compiler.h>
#endif
#include <types.h>

#ifdef __DEF_ALL__

#define L_vqt_fext
#define L_v_ftext
#define L_v_fteof
#define L_v_getout
#define L_vst_scra
#define L_vst_erro
#define L_v_shtext
#define L_vst_arbp
#define L_vst_ar32
#define L_vqt_adva
#define L_vqt_ad32
#define L_vqt_devi
#define L_v_saveca
#define L_v_loadca
#define L_v_flushc
#define L_vst_sets
#define L_vst_se32
#define L_vst_skew
#define L_vqt_get_
#define L_vqt_cach
#define L_vst_char
#define L_vst_kern
#define L_vqt_fnt
#define L_vqt_trac
#define L_vqt_pair
#define L_v_getbit

#endif /* __DEF_ALL__ */

#ifdef L_vqt_fext

/* Inquire Outline Font Text Extent. This function works exactly like
 * vqt_extent(), but the rectangle returned will account for the remainder
 * values of vqt_advance() and kerning.
 */
void vqt_f_extent(int handle, const char *str, int extent[8])
{
    unsigned char ch;
    short *ptr;
    int   *ept, *end;
    
    ptr = _intin;
    while ( ch = *str++)
	*ptr++ = ch;
    *ptr = 0;    
    __vdi__(VDI_CONTRL_ENCODE(240, 0, (int)(ptr - _intin), 0), handle);
    
    ptr = _ptsout;
    ept = extent;
    end = ept + 8;
    do {
	*ept++ = *ptr++;
    } while (ept < end);
}

#endif /* L_vqt_fext */


#ifdef L_v_ftext

/* Outline Font Text. This function works exactly like v_gtext(), but the text
 * returned will account for the remainder values of vqt_advance().  In other
 * words, the text spacing will be more accurate. In addition, for applications
 * that want more control over character placement, v_ftext() will take a
 * custom set of offset vectors, one for each character in the string
 * (including the last one for underlining calculations).  Each vector must  
 * consist of a pair of 16-bit values that will be used in place of a
 * character's advance vector when outputting text.  A second binding follows
 * the original. 
 */
void
v_ftext(int handle, int x, int y, const char *str)
{
    unsigned char   ch;
    short *ptr = _intin;
    
    _ptsin[0] = x;
    _ptsin[1] = y;
    while ( ch  = (unsigned const char) *str++)
	*ptr++ = ch;
    *ptr = 0;
    
    __vdi__(VDI_CONTRL_ENCODE(241, 1, (int)(ptr - _intin), 0), handle);
}

#endif /* L_v_ftext */

#ifdef L_v_fteof
void v_ftext_offset(int handle, int x, int y, const char *str, int *offset)
{
    unsigned char   ch;
    short *ptr = _intin;
    int n = 0;
    
    _ptsin[0] = x;
    _ptsin[1] = y;
    while ( ch  = (unsigned const char) *str++) 
    {
	*ptr++ = ch;
        n++;
    }
    *ptr = 0;

    ptr = &_ptsin[2];
    for(n *= 2; n > 0; n--)
    {
        *ptr++ = *offset++;
    }
    
    __vdi__(VDI_CONTRL_ENCODE(241, 1, (int)(ptr - _intin), 0), handle);
}
#endif /* L_v_fteof */

#ifdef  L_v_killou

#error v_killoutline(int handle, void *component) doesnt exist any more

#endif /* L_v_killou */


#ifdef L_v_getout

/* Generate an outline for character ch, and return the bezier representation
 * in the buffer provided.
 */
void v_getoutline(int handle, int ch, int *xyarray, char *bezarray,
                  int maxverts, int *numverts)
{
    int **addr;
    
    _intin[0] = ch;
    _intin[1] = maxverts;
    addr = (int **)(&_intin[2]);
    *addr++ = xyarray;
    *addr = (int *)bezarray;
    __vdi__(VDI_CONTRL_ENCODE(243, 0, 6, 0), handle);
    *numverts = _intout[0];
}

#endif /* L_v_getout */


#ifdef L_vst_scra

/* Set scratch buffer allocation mode.
 * This buffes is used when creating special effects on fonts.
 * mode=0: (default) account for FSM fonts when allocating scratch buffers
 * mode=1: account only for BM fonts;  no special effects for outlines
 * mode=2: allocate no scratch buffer; no special effects at all
 */
void vst_scratch(int handle, int mode)
{
    _intin[0] = mode;
    __vdi__(VDI_CONTRL_ENCODE(244, 0, 1, 0), handle);
}

#endif /* L_vst_scra */


#ifdef L_vst_erro

/* Set FSM error mode.
 * mode=1: (default) errors go to screen.
 * mode=0: errors reported in error variable `errorvar'.
 */
void vst_error(int handle, int mode, short *errorvar)
{
    
    _intin[0] = mode;
    *(short **)&_intin[1] = &errorvar;
    __vdi__(VDI_CONTRL_ENCODE(245, 0, 3, 0), handle);
}

#endif /* L_vst_erro */


#ifdef L_v_shtext

/* v_gtext with shadow.
 * Text color should be set to `color' before calling.
 * This is not technically an FSM binding,
 * but this module is a convenient place for it.
 */
void v_shtext( int wsid, 
	  int x,
	  int y,
	  const char * text,
	  int color,
	  int xshadow,
	  int yshadow )
{
    __EXTERN void v_ftext __PROTO((int, int, int, const char *));
    __EXTERN int vst_color __PROTO((int, int));

    if( xshadow || yshadow )
    {
	v_ftext( wsid, x+xshadow*2, y+yshadow*2, text );
	(void) vst_color( wsid, 0 );
	v_ftext( wsid, x+xshadow, y+yshadow, text );
	(void) vst_color( wsid, color );
    }
    v_ftext( wsid, x, y, text );
}
#endif /* L_v_shtext */


#ifdef L_vst_arbp

/* Set character cell height to arbitrary value.
 * Height is given in printer points (more or less) and it does not
 * have to be listed in extend.sys.
 * Only for FSM outline fonts.
 */
int vst_arbpt( int handle,
	   int point,
	   int *wchar,
	   int *hchar,
	   int *wcell,
	   int *hcell )
{
    short	*outp = &_ptsout[0];

    _intin[0] = point;
    __vdi__(VDI_CONTRL_ENCODE(246, 0, 1, 0), handle);
    *wchar = *outp++;
    *hchar = *outp++;
    *wcell = *outp++;
    *hcell = *outp;

    return _intout[0];
}
#endif /* L_vst_arbp */

#ifdef L_vst_ar32

/* fix32 version */
long vst_arbpt32( int handle,
	   long point,
	   int *wchar,
	   int *hchar,
	   int *wcell,
	   int *hcell )
{
    short	*outp = &_ptsout[0];

    *((long *)(&_intin[0])) = point;
    __vdi__(VDI_CONTRL_ENCODE(246, 0, 2, 0), handle);
    *wchar = *outp++;
    *hchar = *outp++;
    *wcell = *outp++;
    *hcell = *outp;

    return *((long *)(&_intout[0]));
}
#endif /* L_vst_ar32 */

#ifdef L_vqt_adva

/* Inquire Outline Font Text Advance Placement Vector
 * This function returns the x and y offsets which are needed to  place the
 * next character of a string in the proper position.  This call is necessary
 * when laying down text at rotations other than 0, 90,  and 270.  In addition,
 * the call returns remainder values for the x and y offsets (mod 16000), so
 * that cursor placement can be calculated for v_ftext() and vqt_f_extent().
 *
 * In addition, this call also returns values in units of 1/65536 pixels (fix31
 * format).  The new binding for vqt_advance32() follows, and atari encourages
 * programmers to use the new data type.
 *
 */
void vqt_advance(int handle, int ch, int *xadv, int *yadv, int *xrem,
                 int *yrem) 
{
    short	*outp = &_ptsout[0];

    _intin[0] = ch;
    __vdi__(VDI_CONTRL_ENCODE(247, 0, 1, 0), handle);
    *xadv = *outp++;
    *yadv = *outp++;
    *xrem = *outp++;
    *yrem = *outp;
}
#endif /* L_vqt_adva */

#ifdef L_vqt_ad32
/* new binding. returns results in fix31 (1/64k pixels) types.
 */
void vqt_advance32(int handle, int ch, long *advx, long *advy)
{
    long *outp = (long *)(&_ptsout[4]);

    _intin[0] = ch;
    __vdi__(VDI_CONTRL_ENCODE(247, 0, 1, 0), handle);
    *advx = *outp++;
    *advy = *outp;
}
#endif /* L_vqt_ad32 */

#ifdef L_vqt_devi

/* Inquire device status information.
 * This function takes a device id number as a parameter and reports back to
 * the application whether or not the driver for that device has been installed
 * by gdos. If the driver has been installed, the name of the driver is
 * returned to the application.
 */
void
vqt_devinfo( int handle, int device, int *isdev, char *drivername )
{
    short	*ioutp, *end;

    _intin[0] = device;
    __vdi__(VDI_CONTRL_ENCODE(248, 0, 1, 0), handle);
    if (0 != (*isdev = _ptsout[0])) {
	ioutp = _intout;
	end  = ioutp + _contrl[4];
	do {
	    *drivername++ = (char) *ioutp++;
	} while (ioutp < end);
    }
    *drivername = '\0';
}
#endif /* L_vqt_devi */

#ifdef L_v_saveca

/* Save outline font cache to disk.
 */
int
v_savecache( int handle, char *filename )
{
    short       *inptr = _intin;

    while (*inptr++ = *filename++)
	;	/* nothing */
    __vdi__(VDI_CONTRL_ENCODE(249, 0, (int)(inptr - _intin), 0), handle);

    return _intout[0];
}
#endif /* L_v_saveca */

#ifdef L_v_loadca

/* Load/merge outline font cache from disk.
 * mode = 0 - append
 *      = 1 - flush and load anew
 * returns 0 or -1 if error
 */
int
v_loadcache( int handle, char *filename, int mode )
{
    short *inptr = _intin;

    *inptr++ = mode;
    while (*inptr++ = *filename++)
	;	/* nothing */
    __vdi__(VDI_CONTRL_ENCODE(250, 0, (int)(inptr - _intin), 0), handle);

    return _intout[0];
}
#endif /* L_v_loadca */

#ifdef L_v_flushc

/* Flush outline font cache.
 * return 0 or -1 on error.
 */
int v_flushcache( int handle )
{
    __vdi__(VDI_CONTRL_ENCODE(251, 0, 0, 0), handle);

    return _intout[0];
}
#endif /* L_v_flushc */

#ifdef L_vst_sets

/* Set Character Cell Width by Arbitrary Points. This function sets the current
 * graphic text character width (set size) in printer points.  An arbitrary set
 * size may be entered to represent the character width.  It should be noted
 * that the next call to vst_point, vst_arbpt or vst_height will cancel out
 * this call and  will set the set size to be equal to the requested point
 * size. This call will only work with outline fonts.  The set size may be
 * specified in either 16-bit integer format or 32-bit fix31 format (units of
 * 1/65536 points). 
 */
int vst_setsize( int handle,
	     int point,
	     int *wchar,
	     int *hchar,
	     int *wcell,
	     int *hcell )
{
    short *outp = &_ptsout[0];
    
    _intin[0] = point;
    __vdi__(VDI_CONTRL_ENCODE(252, 0, 1, 0), handle);

    *wchar = *outp++;
    *hchar = *outp++;
    *wcell = *outp++;
    *hcell = *outp;

    return _intout[0];
}
#endif /* L_vst_sets */

#ifdef L_vst_se32

/* new fix31 version
 */

long vst_setsize32( int handle,
	     long point,
	     int *wchar,
	     int *hchar,
	     int *wcell,
	     int *hcell )
{
    short *outp = &_ptsout[0];
    
    *((long *)(&_intin[0])) = point;
    __vdi__(VDI_CONTRL_ENCODE(252, 0, 2, 0), handle);

    *wchar = *outp++;
    *hchar = *outp++;
    *wcell = *outp++;
    *hcell = *outp;

    return *((long *)(&_intout[0]));
}
#endif /* L_vst_se32 */

#ifdef L_vst_skew

/* Set FSM skew. (only works with outline fonts)
 * Skew in tenths of degrees.  Valid values between -900 and 900. (-ve to left)
 */
int vst_skew( int handle, int skew )
{
    _intin[0] = skew;
    __vdi__(VDI_CONTRL_ENCODE(253, 0, 1, 0), handle);

    return _intout[0];
}
#endif /* L_vst_skew */

#ifdef L_vqt_get_

/* Get Character Mapping Table. This call returns the address of a series of
 * contiguous tables used internally by  SpeedoGDOS.  The tables are used to
 * map the Atari character set to the equivalent Bitstream character indexes.
 * Depending on the font file, a Speedo font's indexes have six different
 * formats: the Bitstream International Character Set, the Bitstream
 * International Symbol Set, the Bitstream Dingbats Set, the PostScript text
 * set, the PostScript symbol set, and the PostScript Dingbats set.  There are
 * a total of seven tables which map the Atari character set to Bitstream
 * character indexes, one master mapping, and one table for each of the
 * aforementioned character sets (in the order presented).  Applications can
 * find out which character set corresponds to the current font by checking the
 * Speedo font file header. Each individual table contains 224  word-sized
 * entries with the first entry being the translation for character 32, the
 * second for character 33....etc.  Therefore, with the address of the table,
 * applications can change the mappings so that any Bitstream character index
 * may be substituted.
 */
void vqt_get_table(int handle, short **map)
{
    __vdi__(VDI_CONTRL_ENCODE(254, 0, 0, 0), handle);

    *map = *((short **)(&_intout[0]));
}

#if 0 /* old fsm binding */
/* ----------------------------------------------------------------------
 * Get FSM GASCII tables.
 */
void
vqt_get_tables( int handle, void **gascii, void **style )
{
    __vdi__(VDI_CONTRL_ENCODE(254, 0, 0, 0), handle);
    *gascii = *(void **)&_intout[0];
    *style =  *(void **)&_intout[2];
}
#endif
#endif /* L_vqt_get_ */

#ifdef L_vqt_cach

/* Get Outline Font Cache Size. Returns the largest block size available in
 * each of the two fsm caches.  This call can be used to estimate how big a
 * character SpeedoGDOS can handle when it prints a character.  A zero (0) in
 * which_cache will instruct SpeedoGDOS to return the largest allocatable block
 * in the character bitmap cache.  A one (1) will return the same information
 * for the data structure cache.
 */
void vqt_cachesize( int handle, int which_cache, size_t *size )
{
    _intin[0] = which_cache;
    __vdi__(VDI_CONTRL_ENCODE(255, 0, 1, 0), handle);
    *size = *((size_t *)(&_intout[0]));
}
#endif /* L_vqt_cach */


#ifdef L_vst_char

/* Set Character Mapping Mode. This function allows the application to switch
 * from using the Atari character set to the BICS character set.  The
 * vst_charmap() function will set a flag so that all subsequent calls to text
 * calls will use words that are equivalent to Bitstream character indexes
 * instead of Atari ASCII bytes. 
 */
void vst_charmap(int handle, int mode)
{
    _intin[0] = mode;
    __vdi__(VDI_CONTRL_ENCODE(236, 0, 1, 0), handle);
}    
#endif /* L_vst_char */

#ifdef L_vst_kern

/* Set Kerning Mode. This function allows the application to set the different
 * kerning modes.  Track kerning can have 0-3 tracks:  0 is no kerning, 1 is
 * normal, 2 is tight, and 3 is very tight.  The vst_kern() function passes in
 * a track kern value and it returns the track to which the current font is
 * set.  Pair kerning is set to be on or off. The vst_kern() function will
 * return 0 if there is no track kerning or a number greater than 0 to indicate
 * that pair kerning is on; that number is the number of kerning pairs in the
 * font. 
 */
void vst_kern(int handle, int tmode, int pmode, int *tracks, int *pairs)
{
    _intin[0] = tmode;
    _intin[1] = pmode;
    __vdi__(VDI_CONTRL_ENCODE(237, 0, 2, 0), handle);
    *tracks = _intout[0];
    *pairs  = _intout[1];
}    
#endif /* L_vst_kern */

#ifdef L_vqt_fnt

/* Inquire Speedo Font Header Information. This function copies the current 
 * font's Speedo font header into a buffer and returns the full path name for
 * the corresponding TDF file.  Note that the buffer must be at least 421
 * bytes.  See (nonexistant!) Bitstream documentation for specific font header
 * information.  
 */
void vqt_fontheader(int handle, char *buffer, char *pathname)
{
    short *ptr;
    int n;
    
    *((char **)(&_intin[0])) = buffer;
    __vdi__(VDI_CONTRL_ENCODE(232, 0, 2, 0), handle);
    
    for(ptr = &_intout[0], n = _contrl[4]; n > 0; n--)
        *pathname++ = *ptr++;
}    
#endif /* L_vqt_fnt */

#ifdef L_vqt_trac

/* Inquire Track Kerning Information. This function allows the application to
 * inquire the adjustment vector for track kerning.  The vqt_trackkern()
 * function returns the vector (x-direction and  y-direction) that indicates
 * the spacing adjustment made between characters. 
 */
void vqt_trackkern(int handle, long *x, long *y)
{
    __vdi__(VDI_CONTRL_ENCODE(234, 0, 0, 0), handle);
    *x = *((long *)(&_ptsout[0]));
    *y = *((long *)(&_ptsout[2]));
}
#endif /* L_vqt_trac */

#ifdef L_vqt_pair

/* Inquire Pair Kerning Information. This function allows the application to
 * inquire the adjustment vector for pair kerning.  The vqt_pairkern() function
 * returns the vector (x-direction and y-direction) that indicates the spacing
 * adjustment made between the character pair specified.
 */
void vqt_pairkern(int handle, int ch1, int ch2, long *x, long *y)
{
    _intin[0] = ch1;
    _intin[1] = ch2;
    /* atari doc is wrong about contrl[3] */
    __vdi__(VDI_CONTRL_ENCODE(235, 0, 2, 0), handle);
    *x = *((long *)(&_ptsout[0]));
    *y = *((long *)(&_ptsout[2]));
}
#endif /* L_vqt_pair */

#ifdef L_v_getbit

/* Get Character Bitmap Information. This call provides information to allow
 * the caller to know the exact size and placement of a given character.  This
 * information includes the character's x and y advance vectors, the x and y
 * offsets, and the bitmap dimensions of the character. The advance vector
 * represents the amount to add to the current point to place the following
 * character.  The x and y offsets, when added to the current point, give the
 * caller the location of the upper left hand corner of the bitmap.  The width
 * and height of the bitmap are returned as 16 bit integers.  All other values
 * are returned in fix31 representation.
 */
void v_getbitmap_info(int handle,
                      int ch, 
                      long *advancex, long *advancey,
                      long *xoffset, long *yoffset,
                      int *width, int *height,
                      short **bitmap)
{
    _intin[0] = ch;
    __vdi__(VDI_CONTRL_ENCODE(239, 0, 1, 0), handle);
    *width = _intout[0];
    *height = _intout[1];
    *advancex = *((long *)(&_intout[2]));
    *advancey = *((long *)(&_intout[4]));
    *xoffset = *((long *)(&_intout[6]));
    *yoffset = *((long *)(&_intout[8]));
    *bitmap = *((short **)(&_intout[10]));
}
#endif /* L_v_getbit */

/* -eof- */
