#include #include #include "grafprt.h" #include "grafstr.h" #define PI 3.141592653589793238 /*--------------------------------------------------------------------*/ /* module grafstr.c in turbo c version 2.0, large code model. */ /* */ /* a set of graphics string routines for high-resolution printer */ /* graphics on epson FX, LX and other IBM Graphics Printer */ /* compatibles. it is intented for use with module grafprt. */ /* the whole thing is a bit of a kludge, but it will work if you */ /* don't have anything better. */ /* */ /* sample usage: */ /* */ /* initgrafprt(); */ /* portrait(); */ /* frame(); */ /* defreg(0.0,1.0,0.5,2.0,200,860,700,1500); */ /* framxy(); */ /* prtstr("This is a test",0.5,1.2,0,4,2); */ /* prntgr(0); */ /* */ /* released to the public domain by Gregory K. Landheim on January */ /* 1, 1989, (c) all rights reserved. anybody is authorized to use */ /* this code for any purpose whatsoever on the condition that they */ /* realize I assume absolutely no liability and give no warrantee */ /* for its use or performance. it is distributed "as is", and if */ /* you use it you assume full liability for its use. */ /* */ /*--------------------------------------------------------------------*/ /* */ /* aspect_and_ */ /* rotate() aspect ratio correction and rotation for strings. */ /* swapmode() swaps between portrait and landscape modes. */ /* intprntstr() prints a string at (ix,iy) in integer world coords. */ /* prtstr() prints a string at (x,y) in real world coordinates. */ /* */ /*--------------------------------------------------------------------*/ float Cos_rot,Sin_rot; /*--------------------------------------------------------------------*/ /* The global array, F, is a font description table for drawing */ /* vector graphics characters. The characters form a 5 by 10 */ /* matrix: */ /* */ /* 0 1 2 3 4 --- A B C D E */ /* 5 6 7 8 9 | F G H I J */ /* 10 11 12 13 14 | K L M N O */ /* 15 16 17 18 19 | P Q R S T */ /* 20 21 22 23 24 | U V W X Y */ /* 25 26 27 28 29 | Z [ \ ] ^ */ /* 30 31 32 33 34 --- _ ` a b c */ /* 35 36 37 38 39 d e f g h */ /* 40 41 42 43 44 i j k l m */ /* 45 46 47 48 49 n o p q r */ /* */ /* Each position in the 5 by 10 grid is represented by a number */ /* which has an equivalent ascii character representation. In the */ /* example given above, the letter 'I' is drawn by drawing the */ /* lines 1-3, 2-32, 31-33. This translates to the ascii charac- */ /* ters B-D, C-a, `-b. Thus, the character 'I' is represented by */ /* the string "BDCa`b". The rest of the printable ascii characters*/ /* are likewise represented below. */ /*--------------------------------------------------------------------*/ static char *F[94] = { /* */ "", /* ! */ "CW\\a", /* " */ "BLDN", /* # */ "B`DbKOUY", /* $ */ "OIIGGKKQQSSYY]][[UCa", /* % */ "BFFLLHHBBEE_X\\\\bb^^X", /* & */ "Yaa``ZZUUIIDDCCGGLLc", /* ' */ "CHHL", /* ( */ "DGG[[b", /* ) */ "BII]]`", /* * */ "CaF^JZ", /* + */ "H\\PT", /* , */ "affj", /* - */ "PT", /* . */ "`a", /* / */ "E_", /* 0 */ "BFFZZ``bb^^JJDDB", /* 1 */ "GCCa`b", /* 2 */ "FBBDDJJOOZZ__c", /* 3 */ "FBBDDJJOOSSQSYY^^bb``Z", /* 4 */ "YUUDDbac", /* 5 */ "EAAKKNNTT^^bb``Z", /* 6 */ "JDDBBFFZZ``bb^^YYSSQQU", /* 7 */ "FAAEEZZ_", /* 8 */ "BFFKKQQUUZZ``bb^^YYSSOOJJDDBQS", /* 9 */ "TQQKKFFBBDDJJ^^bb``Z", /* : */ "MR\\a", /* ; */ "RWaffj", /* < */ "EPPc", /* = */ "KOUY", /* > */ "ATT_", /* ? */ "FBBDDJJOOSSRRW\\a", /* @ */ "c``ZZFFBBDDJJYYVVLLN", /* A */ "_CCcQS", /* B */ "_AADDJJOOSSPSYY^^bb_", /* C */ "JDDBBFFZZ``bb^", /* D */ "_AADDJJ^^bb_", /* E */ "EAA__cPR", /* F */ "EAA_PR", /* G */ "JDDBBFFZZ``bb^^YYX", /* H */ "A_EcPT", /* I */ "BDCa`b", /* J */ "CED]]aa``Z", /* K */ "A_EPPc", /* L */ "A__cc^", /* M */ "_AARREEc", /* N */ "_AAccE", /* O */ "BFFZZ``bb^^JJDDB", /* P */ "_AADDJJOOSSP", /* Q */ "BFFZZ``bb^^JJDDB]h", /* R */ "_AADDJJOOSSPRc", /* S */ "JDDBBFFKKQQSSYY^^bb``Z", /* T */ "AECa", /* U */ "AZZ``bb^^E", /* V */ "AaaE", /* W */ "A__WWccE", /* X */ "Ac_E", /* Y */ "ARRERa", /* Z */ "AEE__c", /* [ */ "CBB``a", /* \ */ "Ac", /* ] */ "CDDbba", /* ^ */ "KCCO", /* _ */ "dh", /* ` */ "CHHN", /* a */ "PLLNNTT^^bb``ZZUUY^c", /* b */ "A_PSSYY^^bb_", /* c */ "TNNLLPPZZ``bb^", /* d */ "EcTQQUUZZ``c", /* e */ "UYYTTNNLLPPZZ``bb^", /* f */ "JDDCCGG`PR", /* g */ "^bb``ZZPPLLNNTTmmqqooi", /* h */ "A_UQQSSYYc", /* i */ "Ra`bCH", /* j */ "OmmqqooiidEJ", /* k */ "A_HPPc", /* l */ "BCCa`b", /* m */ "_PPLLRRWRNNTTc", /* n */ "K_PLLNNTTc", /* o */ "LPPZZ``bb^^TTNNL", /* p */ "KnPLLNNTT^^bb_", /* q */ "OrTNNLLPPZZ``c", /* r */ "K_PLLNNT", /* s */ "TNNLLPPVVXX^^bb``Z", /* t */ "C\\\\bb^LN", /* u */ "KZZ``bb^^O^c", /* v */ "KaaO", /* w */ "K__WWccO", /* x */ "KcO_", /* y */ "KZZ``bb^^O^mmqqooi", /* z */ "KOO__c", /* { */ "DCCGGLLPPVV[[aab", /* | */ "Ca", /* } */ "BCCIINNTTXX]]aa`"}; /*--------------------------------------------------------------------*/ /* */ /* void aspect_and_rotate(int angle,int ix0,int iy0, */ /* int *ix2,int *iy2) */ /* */ /* Rotates a character string pixel located at integer position */ /* (ix2,iy2) through an angle, with the pixel at integer position */ /* (ix0,iy0) serving as the pivot point. also performs scaling as a */ /* function of aspect ratio. */ /* */ /*--------------------------------------------------------------------*/ void aspect_and_rotate(int angle,int ix0,int iy0,int *ix2,int *iy2) { extern int Arx,Ary; /* declared in module grafprt */ int idelta_x,idelta_y; float delta_x, delta_y; idelta_x = *ix2-ix0; idelta_y = *iy2-iy0; /* for the cardinal directions, just exchange coordinates and make */ /* aspect ratio correction: */ switch (angle) { case (90) : { *ix2 = ix0 - idelta_y; *iy2 = iy0 + (idelta_x * Ary) / Arx; break; } case (180) : { *ix2 = ix0 - idelta_x; *iy2 = iy0 - (idelta_y * Ary) / Arx; break; } case (270) : { *ix2 = ix0 + idelta_y; *iy2 = iy0 - (idelta_x * Ary) / Arx; break; } case (0) : case (360) : { *ix2 = ix0 + idelta_x; *iy2 = iy0 + (idelta_y * Ary) / Arx; break; } default : { delta_x = idelta_x*Cos_rot - idelta_y*Sin_rot; delta_y = idelta_y*Cos_rot + idelta_x*Sin_rot; *ix2 = ix0 + (int) delta_x; *iy2 = iy0 + (int) ((delta_y * Ary) / Arx); break; } } /* end, case of angle */ } /* void aspect_and_rotate() */ /*--------------------------------------------------------------------*/ /* */ /* void swapmode(int toportrait) */ /* */ /* The string routines were designed for portrait mode. When used */ /* in landscape mode the easiest kludge I came up with involved */ /* swapping the appropriate globals from module grafprt and doing */ /* the string drawing in portrait mode, after a suitable rotation, */ /* performed in the calling function. */ /* It is called either to switch to portrait mode constant values */ /* or to switch back to landscape mode constants. */ /* */ /*--------------------------------------------------------------------*/ void swapmode(int toportrait) { /* externals are declared in module grafprt */ extern int IX_min,IX_max,IY_min,IY_max,IDw,IDh,Maxheight; extern float X_min,X_max,Y_min,Y_max,Dw,Dh; int temp1,temp2; float temp; if (toportrait) { temp1 = IX_min; temp2 = IX_max; IX_min = IY_min; IX_max = IY_max; IY_min = Maxheight - temp2; IY_max = Maxheight - temp1; } else { temp1 = IY_min; temp2 = IY_max; IY_min = IX_min; IY_max = IX_max; IX_min = Maxheight - temp2; IX_max = Maxheight - temp1; } temp = X_min; X_min = Y_min; Y_min = temp; temp = X_max; X_max = Y_max; Y_max = temp; Dw = X_max - X_min; Dh = Y_max - Y_min; IDw = IX_max - IX_min; IDh = IY_max - IY_min; } /* void swapmode() */ /*--------------------------------------------------------------------*/ /* */ /* void intprntstr(char *astring,int ix0,int iy0, */ /* int angle,int size,int center) */ /* */ /* Prints a string of ASCII characters (ASCII 32 through 125) at */ /* integer world position (ix0,iy0). */ /* */ /* initgrafprt() must be called before calling intprntstr() */ /* defreg() must be called before calling intprntstr() */ /* colorset() must be called before calling intprntstr() */ /* */ /*--------------------------------------------------------------------*/ /* */ /* char *astring String of ASCII characters to draw. */ /* int ix0 X-coordinate at which to print string. */ /* int iy0 Y-coordinate at which to print string. */ /* int angle Angle (in degrees) through which to rotate the */ /* string counterclockwise from the x-axis. */ /* int size size of character to draw. 1 through whatever. */ /* int center Determines how to center the string with respect */ /* to the integer world coordinates (ix0,iy0). */ /* = 0 : (ix0,iy0) is center of left edge of string. */ /* = 1 : (ix0,iy0) is center of string. */ /* = 2 : (ix0,iy0) is center of right edge of string. */ /* */ /*--------------------------------------------------------------------*/ void intprntstr(char *astring,int ix0,int iy0, int angle,int size,int center) { extern int Arx,Ary; /* declared in module grafprt */ extern int Portrait; /* declared in module grafprt */ int char_num,i; int ix,iy,n1,n2; int ix1,iy1,ix2,iy2; int string_length; int character; int nypixels,npixels; int char_spacing; float theta; int savmode,swapped; swapped = 0; if (!Portrait) { savmode = Portrait; Portrait = 1; swapped = 1; angle = angle + 270; swapmode(1); } char_spacing = 6; string_length = (int)strlen(astring); theta = angle * PI / 180.0; /* converts degrees to radians */ /* get the (global) rotation parameters: */ Sin_rot = (float) sin(theta); Cos_rot = (float) cos(theta); /* perform the string centering by moving the string pivot point as */ /* a function of 'theta' and 'center': */ switch (center) { case (1) : { npixels = size * (char_spacing * string_length - 2); nypixels = (npixels * Ary) / Arx; iy0 = iy0 - nypixels * Sin_rot / 2; ix0 = ix0 - npixels * Cos_rot / 2; break; } case (2) : { npixels = size * (char_spacing * string_length - 2); nypixels = (int)((npixels * Ary) / Arx); iy0 = iy0 - nypixels * Sin_rot; ix0 = ix0 - npixels * Cos_rot; break; } } /* case of center */ iy = iy0 + (int)(((3 * size * Ary) * Cos_rot) / Arx); ix0 = ix0 - (int)((3 * size) * Sin_rot); /* plot the characters one at a time, looping over the string */ for (character=0; character