/*********************************************************************** * * TITLE: * gr_plot.c * * AUTHOR: * Kevin J. Miller, Ana Maria Guerrero, Chester Joe * * DESCRIPTION: * This module is the source code for the gr_ graphics ploting * routines. * * CHANGE HISTORY * * $Log: gr_plot.c,v $ * Revision 1.40 1997/01/17 03:59:18 kevin * now works in command line mode * PostScript output conforms to standard * can generate pre-PDF PostScript * * Revision 1.39 1997/01/01 02:03:31 kevin * fixed compiler warnings * added short dotted lines * * Revision 1.38 1996/11/21 18:29:25 ryan * Fixed refreshing problem in gr_rotate_text. * * Revision 1.37 1995/09/30 23:22:32 kevin * <> * cache colors in local linked list * * Revision 1.36 1995/05/02 23:24:26 kevin * added windows set pixel command * * Revision 1.35 1994/11/30 02:17:23 kevin * added gr_circle_fill * * Revision 1.34 1994/07/15 21:36:40 kevin * updated PICT commands for sfosedt & xopps * * Revision 1.33 1994/06/17 03:48:03 kevin * make option for AppleSingle or PICT * * Revision 1.32 1994/06/15 03:17:36 kevin * updated metafile commands * * Revision 1.31 1994/06/15 00:05:26 kevin * updated constants * * Revision 1.30 1994/06/14 03:15:13 kevin * added gr_point function * * Revision 1.29 1994/05/20 22:40:35 kevin * removed unnecessary gc_val * * Revision 1.28 1994/05/16 18:47:46 kevin * added partial WMF & univeral header * * Revision 1.27 1994/04/29 00:19:02 kevin * ANSI port - first stage * * Revision 1.26 1993/11/15 23:46:22 kevin * added subset of PICT codes * * Revision 1.25 1993/02/09 17:24:12 jjj * enabled rotate_text to handle null strings. * * Revision 1.24 1993/02/09 17:23:38 clm * fixed gr_rect_clear * * Revision 1.23 1992/12/31 02:53:52 chester * add gr_rotate_text function for rotated text. * add gr_set_clip and gr_reset_clip. * * Revision 1.22 1992/12/30 23:13:16 chester * add gr_current_state function to get current graphics state. * add gr_masked_line function for lines with a white background. * add gr_poly_clear for whiting out a polygon. * * Revision 1.21 1992/01/13 16:17:47 ana * Added the "letter" command to gr_laser_on. * * Revision 1.20 1991/11/23 02:38:40 kevin * reset current font to UNKNOWN each time screen is turned on * * Revision 1.19 1991/10/31 21:33:52 chester * fixed the gr_poly laser stroke bug. * * Revision 1.18 1991/10/04 16:53:49 chester * remove gr_curve and math library from gr routines * * Revision 1.17 1991/09/16 17:07:42 chester * fixed line connection bug in gr_poly function. * * Revision 1.16 1991/09/06 19:51:13 ana * Added gr_rect_shade() * * Revision 1.15 1991/08/28 20:22:28 chester * corrected the bug in gr..._fill routines. * * Revision 1.14 1991/08/28 19:58:31 chester * change Pixel to unsigned long. * * Revision 1.13 1991/08/27 20:55:28 chester * added ana's gr_init_colors, gr_hilight functions. * * Revision 1.12 1991/08/27 20:18:46 chester * moved NUM_FONTS constant to header file. * added different line types to draw. * added gr_set_line function to change drawing line type. * added gr_poly_fill to draw a filled polygon. * added gr_rect_fill to draw a filled rectangle. * added more fonts to screen font. * added masking variable to gr_text. * * Revision 1.11 1991/08/27 20:11:07 kevin * added standard headers * * Revision 1.10 1991/04/30 00:06:45 kevin * de-linted and added comments * * Revision 1.9 1991/04/29 19:56:48 kevin * added standard header * * Revision 1.8 1991/04/23 23:23:47 kevin * fixed unnecessary include of Motif * * Revision 1.7 1990/12/28 15:42:39 kevin * now use image function to match screen behavior * * Revision 1.6 90/12/28 13:02:53 kevin * changed name to gr_ and fixed so there is only one include * * Revision 1.5 90/12/27 17:21:52 kevin * finished up new image routines * * Revision 1.4 90/12/19 14:28:06 kevin * removed memory functions, and added a screen font routine * * Revision 1.3 90/12/12 09:10:12 ana * Added gr_image. * * Revision 1.2 90/11/29 15:35:29 ana * New Version. * *********************************************************************** * * WARNINGS: * * EXTERNAL CALLABLE COMPONENTS (PUBLIC): * void gr_init(int, int, int, char *) * void gr_init_colors(unsigned long, unsigned long, unsigned long) * int gr_current_state(void) * void gr_screen_on(GRDisplay *) * void gr_screen_off(void) * void gr_laser_on(FILE *, int) * void gr_laser_off(void) * int gr_pict_on(char *, int) * void gr_pict_off(void) * int gr_wmf_on(char *) * void gr_wmf_off(void) * int gr_debug_on(char *) * void gr_debug_off(void) * void gr_point(int, int) * void gr_move(int, int) * void gr_set_line(int) * void gr_draw(int, int) * void gr_line(int, int, int, int) * void gr_masked_line(int, int, int, int) * void gr_arc(int, int, int, int, int, int) * void gr_circle(int, int, int) * void gr_circle_fill(int, int, int) * void gr_poly(XPoint *, int) * void gr_rectangle(int, int, int, int) * void gr_clear(void) * void gr_page(void) * void gr_poly_clear(XPoint *, int) * void gr_rect_clear(int, int, int, int) * void gr_poly_fill(XPoint *, int, char *, int) * void gr_rect_fill(int, int, int, int, char *, int) * void gr_rect_shade(int, int, int, int, int) * void gr_hilight(int, int, int, int) * void gr_free_fonts(void) * void gr_text(int, int, char *, int, int, int) * void gr_rotate_text(int, int, char *, int, int) * void gr_vert_text(int, int, char *, int, int, int) * int gr_strwidth(char *, int) * int gr_txwidth(int) * int gr_txheight(int) * int gr_txdescent(int) * int gr_txascent(int) * void gr_set_color(char *, int) * void gr_image(int, int, GRBitmap *, GRBitmap *, int) * void gr_set_clip(int, int, int, int, Region) * void gr_reset_clip(void) * * GLOBALS: * None * * WAIVERS: * None * * NOTES: * None * * MANUAL PAGE: * See the header file: gr_plot.h * ***********************************************************************/ #ifndef lint static const char rcsid[] = "$Id: gr_plot.c,v 1.40 1997/01/17 03:59:18 kevin OEL $"; #endif #include #include #include #include #include #include #include "gr_plot.h" #ifdef spr extern void *memset(void *, int, size_t); #endif #define BATCH_SIZE 512 static enum { /* current output device */ GR_OFF, GR_SCREEN, GR_LASER, GR_PICT, GR_WMF, GR_DEBUG } gr_state; static enum { /* handles stroke in PostScript */ PS_PATH_OFF, PS_PATH_ON } ps_state; #define MAX_PS_PATH_LEN 100 static ps_path_len; /* length of current path */ static GRDisplay *xdw; /* all display identifiers */ static FILE *lp; /* printer file pointer */ static int xo, yo; /* current position */ static int xp, yp; /* start of path for PostScript */ static int p_height; /* page height */ static int p_width; /* page width */ static int p_mode; /* laser printer rotation mode */ static char *title; /* title of output */ static int page_no; /* page number in file */ static unsigned long background; /* background color index */ static unsigned long foreground; /* foreground color index */ static unsigned long highlight; /* highlight color index */ static int line_state; /* Solid, Dashed, Dotted... */ static unsigned long ps_fonts; /* PostScript fonts used */ static char *ps_fontnames[] = { /* PostScript font names */ "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique", "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique", "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic", "Symbol" }; static FILE *pict_fp; /* Mac PICT file pointer */ static int pict_apple_single; /* TRUE if using AppleSingle format */ static int pict_font; /* old font value */ static FILE *wmf_fp; /* Windows Metafile file pointer */ static long wmf_size; /* size of metafile in 16 bit words */ static long wmf_maxrec; /* maximum record size */ static int wmf_font; /* current font index */ static char *out_buffer = NULL; /* output buffer */ static unsigned int out_avail = 0; /* size of output buffer */ static unsigned int out_len; /* length of current record */ static FILE *debug_fp; /* debug file pointer */ /* * local function prototypes */ static void open_xfont(char *, int); static void screen_font(int); static void set_font(int); static int char_mid(char *); static unsigned int find_color_black(char *); static int pict_open(char *, int); static void pict_cmd(int); static void pict_i16(int); static void pict_i32(long); static void pict_str(char *, int); static void pict_set(int, int); static void pict_out(void); static void pict_close(void); static int wmf_open(char *); static void wmf_cmd(int); static void wmf_i16(int); static void wmf_i32(long); static void wmf_str(char *, int); static void wmf_out(void); static void wmf_close(void); #define NUM_FONTS 96 static int nfonts; /* current number of fonts */ struct font_info { /* font array to hold info */ int fontnumber; int index; XFontStruct *font_struct; }; static struct font_info cur_font; static struct font_info x_fonts[NUM_FONTS]; static char dotted[2] = {1, 3}; static char short_dot[2] = {1, 1}; static char short_dashed[2] = {4, 4}; static char long_dashed[2] = {6, 4}; static Region save_clip_region = NULL; /* holds the original clip region */ static Region sub_region = NULL; /* holds the new clip region */ static Region sub_region2 = NULL; /* holds the new clip region */ /* * conversion for laser printer coordinates */ #define scx(x) ((double)(x)) #define scy(y) ((double)(p_height - (y))) /* * conversion for PICT coordinates */ #define psc(z) ((72 * (z)) / ((p_mode & GR_EXPAND) ? 100 : 75)) /* arc constants */ #define X_DEGREES 64 #define FULL_CIRCLE 360 /* font mask constants */ #define POINTMASK 0xff #define NAMEMASK 0xff00 /* * Apple Single codes */ #define APPLE_SINGLE_MAGIC 0x51600 #define APPLE_SINGLE_VERSION 0x20000 #define APPLE_SINGLE_FINDER_INFO 9 #define APPLE_SINGLE_DATA_FORK 1 /* * PICT opcodes */ #define PICT_NOP 0x00 #define PICT_CLIP 0x01 #define PICT_BKPAT 0x02 #define PICT_TXFONT 0x03 #define PICT_TXFACE 0x04 #define PICT_TXMODE 0x05 #define PICT_SPEXTRA 0x06 #define PICT_PNSIZE 0x07 #define PICT_PNMODE 0x08 #define PICT_PNPAT 0x09 #define PICT_TXSIZE 0x0d #define PICT_VERSION 0x11 #define PICT_LINE 0x20 #define PICT_LONGTEXT 0x28 #define PICT_DVTEXT 0x2a #define PICT_FRAMERECT 0x30 #define PICT_ERASERECT 0x32 #define PICT_FILLRECT 0x34 #define PICT_FRAMEOVAL 0x50 #define PICT_ERASEOVAL 0x52 #define PICT_FILLOVAL 0x54 #define PICT_FRAMEPOLY 0x70 #define PICT_ERASEPOLY 0x72 #define PICT_FILLPOLY 0x74 #define PICT_END (char)0xff /* * Windows Metafile opcodes */ #define WMF_SETMAPMODE 0x0103 #define WMF_SELECTOBJECT 0x012d #define WMF_SETWINDOWORG 0x020b #define WMF_SETWINDOWEXT 0x020c #define WMF_LINETO 0x0213 #define WMF_MOVETO 0x0214 #define WMF_DELETEOBJECT 0x01f0 #define WMF_CREATEPENINDIRECT 0x02fa #define WMF_CREATEFONTINDIRECT 0x02fb #define WMF_CREATEBRUSHINDIRECT 0x02fc #define WMF_POLYGON 0x0324 #define WMF_POLYLINE 0x0325 #define WMF_TEXTOUT 0x0521 #define WMF_SETPIXEL 0x041f /* * font metrics to use when program is in command line mode */ static struct { short font; char width; char height; char descent; char ascent; char cwidths[256]; } font_metrics[] = { { 8, 5, 9, 2, 7, { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 } }, { 10, 6, 10, 2, 8, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 } }, { 12, 7, 13, 3, 10, { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 } }, { 14, 9, 15, 3, 12, { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 } }, { 18, 11, 18, 4, 14, { 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 } }, { 24, 15, 24, 5, 19, { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 } }, { 264, 5, 9, 2, 7, { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 } }, { 266, 6, 10, 2, 8, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 } }, { 268, 7, 13, 3, 10, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 } }, { 270, 9, 15, 3, 12, { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 } }, { 274, 11, 18, 4, 14, { 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 } }, { 280, 15, 24, 5, 19, { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 } }, { 520, 5, 9, 2, 7, { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 } }, { 522, 6, 10, 2, 8, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 } }, { 524, 7, 13, 3, 10, { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 } }, { 526, 9, 15, 3, 12, { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 } }, { 530, 11, 18, 4, 14, { 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 } }, { 536, 15, 24, 5, 19, { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 } }, { 776, 5, 9, 2, 7, { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 } }, { 778, 6, 10, 2, 8, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 } }, { 780, 7, 13, 3, 10, { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 } }, { 782, 9, 15, 3, 12, { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 } }, { 786, 11, 18, 4, 14, { 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 } }, { 792, 15, 24, 5, 19, { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 } }, { 1032, 9, 10, 2, 8, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 5, 5, 7, 6, 2, 3, 3, 3, 5, 2, 6, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 4, 5, 5, 9, 6, 6, 6, 6, 6, 5, 6, 6, 2, 4, 6, 5, 7, 6, 6, 6, 6, 6, 6, 4, 6, 6, 7, 6, 6, 6, 2, 2, 2, 5, 5, 2, 4, 5, 4, 5, 4, 3, 5, 5, 2, 2, 4, 2, 6, 5, 5, 5, 5, 3, 4, 3, 4, 5, 6, 5, 4, 4, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 4, 6, 2, 5, 2, 7, 3, 5, 6, 3, 7, 2, 3, 5, 2, 2, 2, 4, 5, 2, 2, 2, 3, 5, 7, 7, 7, 5, 6, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 5, 4 } }, { 1034, 11, 12, 2, 10, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 6, 6, 9, 8, 3, 4, 4, 4, 6, 3, 7, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 6, 5, 6, 6, 11, 7, 7, 8, 8, 7, 6, 8, 8, 3, 5, 7, 6, 9, 8, 8, 7, 8, 7, 7, 5, 8, 7, 9, 7, 7, 7, 3, 3, 3, 6, 6, 3, 5, 6, 5, 6, 5, 4, 6, 6, 2, 2, 5, 2, 8, 6, 6, 6, 6, 4, 5, 4, 5, 6, 8, 6, 5, 5, 3, 3, 3, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 6, 5, 6, 3, 6, 3, 9, 4, 6, 7, 4, 9, 3, 4, 6, 3, 3, 3, 5, 6, 3, 3, 3, 4, 6, 9, 9, 9, 6, 7, 7, 7, 7, 7, 7, 10, 8, 7, 7, 7, 7, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 6, 8, 8, 8, 8, 8, 7, 7, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 5, 5, 2, 2, 2, 2, 6, 5, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 6, 5 } }, { 1036, 12, 14, 3, 11, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 5, 7, 7, 11, 9, 3, 4, 4, 5, 7, 4, 8, 3, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 7, 7, 7, 7, 12, 9, 8, 9, 9, 8, 8, 9, 9, 3, 7, 8, 7, 11, 9, 10, 8, 10, 8, 8, 7, 8, 9, 11, 9, 9, 9, 3, 4, 3, 6, 7, 3, 7, 7, 7, 7, 7, 3, 7, 7, 3, 3, 6, 3, 9, 7, 7, 7, 7, 4, 6, 3, 7, 7, 9, 6, 7, 6, 4, 3, 4, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 7, 7, 7, 7, 3, 6, 3, 11, 5, 7, 8, 5, 11, 4, 5, 7, 4, 4, 2, 7, 7, 3, 3, 4, 5, 7, 10, 10, 10, 7, 9, 9, 9, 9, 9, 9, 11, 9, 8, 8, 8, 8, 3, 3, 3, 3, 9, 9, 10, 10, 10, 10, 10, 7, 10, 8, 8, 8, 8, 9, 8, 7, 7, 7, 7, 7, 7, 7, 11, 7, 7, 7, 7, 7, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 } }, { 1038, 15, 16, 3, 13, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 8, 8, 12, 10, 3, 5, 5, 7, 9, 3, 9, 3, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 3, 4, 8, 9, 8, 8, 13, 11, 9, 10, 10, 9, 9, 11, 10, 5, 8, 10, 8, 13, 10, 11, 9, 11, 9, 9, 9, 10, 11, 15, 10, 9, 9, 4, 4, 4, 7, 8, 3, 8, 8, 8, 8, 8, 3, 8, 8, 3, 3, 7, 3, 11, 8, 8, 8, 8, 5, 8, 4, 8, 8, 10, 7, 7, 7, 5, 3, 5, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 7, 3, 8, 5, 12, 6, 8, 9, 5, 12, 4, 6, 9, 5, 5, 5, 8, 8, 4, 5, 5, 6, 8, 12, 12, 12, 8, 11, 11, 11, 11, 11, 11, 14, 10, 9, 9, 9, 9, 5, 5, 5, 5, 10, 10, 11, 11, 11, 11, 11, 9, 11, 10, 10, 10, 10, 9, 9, 7, 8, 8, 8, 8, 8, 8, 13, 8, 8, 8, 8, 8, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 7, 8, 7 } }, { 1042, 18, 21, 5, 16, { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 10, 10, 16, 13, 4, 6, 6, 7, 10, 5, 11, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 5, 5, 10, 11, 10, 10, 18, 12, 13, 14, 13, 11, 11, 14, 13, 6, 10, 13, 10, 16, 13, 15, 12, 15, 12, 13, 12, 13, 14, 18, 13, 14, 12, 5, 5, 5, 9, 10, 4, 9, 11, 10, 11, 10, 6, 11, 10, 4, 4, 9, 4, 14, 10, 11, 11, 11, 6, 9, 6, 10, 10, 14, 10, 10, 9, 6, 4, 6, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 10, 10, 10, 10, 4, 10, 6, 15, 7, 9, 11, 7, 14, 5, 7, 10, 6, 6, 4, 10, 10, 4, 5, 6, 7, 9, 15, 15, 15, 10, 12, 12, 12, 12, 12, 12, 18, 14, 11, 11, 11, 11, 6, 6, 6, 6, 13, 13, 15, 15, 15, 15, 15, 10, 15, 13, 13, 13, 13, 14, 12, 9, 9, 9, 9, 9, 9, 9, 15, 10, 10, 10, 10, 10, 4, 4, 4, 4, 11, 10, 11, 11, 11, 11, 11, 10, 11, 10, 10, 10, 10, 10, 11, 10 } }, { 1048, 25, 27, 5, 22, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 14, 13, 22, 17, 6, 8, 8, 10, 14, 6, 15, 6, 7, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 15, 15, 15, 12, 25, 17, 17, 18, 18, 16, 14, 19, 18, 8, 13, 18, 14, 21, 18, 18, 16, 18, 17, 16, 16, 18, 17, 22, 17, 16, 15, 7, 7, 7, 12, 14, 6, 13, 14, 12, 14, 13, 8, 14, 13, 6, 6, 12, 6, 20, 14, 13, 14, 14, 9, 12, 8, 14, 13, 18, 12, 13, 12, 8, 6, 8, 14, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 14, 13, 14, 6, 13, 8, 19, 9, 14, 15, 8, 19, 8, 9, 14, 7, 7, 7, 14, 12, 6, 7, 7, 9, 14, 19, 19, 19, 12, 17, 17, 17, 17, 17, 17, 23, 18, 16, 16, 16, 16, 8, 8, 8, 8, 18, 18, 18, 18, 18, 18, 18, 14, 18, 18, 18, 18, 18, 16, 16, 15, 13, 13, 13, 13, 13, 13, 21, 12, 13, 13, 13, 13, 6, 6, 6, 6, 13, 14, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 13, 14, 13 } }, { 1288, 9, 10, 2, 8, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 5, 6, 6, 2, 3, 3, 3, 5, 2, 6, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 4, 5, 4, 5, 9, 6, 6, 6, 6, 5, 5, 6, 6, 2, 5, 6, 5, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 9, 6, 7, 6, 3, 3, 3, 4, 5, 2, 5, 5, 4, 5, 5, 3, 5, 5, 2, 2, 5, 2, 7, 5, 5, 5, 5, 3, 5, 3, 5, 5, 6, 6, 5, 5, 4, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 5, 5, 5, 6, 2, 5, 2, 8, 4, 6, 6, 4, 8, 2, 3, 5, 2, 2, 2, 5, 5, 2, 2, 2, 4, 6, 7, 7, 7, 5, 6, 6, 6, 6, 6, 6, 8, 6, 5, 5, 5, 5, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 7, 6, 5, 5, 5, 5, 5, 5, 5, 7, 4, 5, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 } }, { 1290, 11, 12, 2, 10, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 6, 8, 8, 3, 4, 4, 4, 6, 3, 7, 3, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 5, 6, 5, 6, 11, 8, 7, 8, 7, 6, 6, 8, 7, 3, 6, 7, 6, 10, 8, 8, 7, 8, 7, 7, 7, 7, 8, 11, 8, 9, 7, 4, 4, 4, 5, 6, 3, 6, 6, 5, 6, 6, 4, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 6, 4, 6, 6, 8, 7, 6, 6, 5, 3, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 6, 6, 6, 7, 3, 6, 3, 10, 5, 7, 7, 5, 10, 3, 4, 6, 3, 3, 3, 6, 6, 3, 3, 3, 5, 7, 9, 9, 9, 6, 8, 8, 8, 8, 8, 8, 10, 8, 6, 6, 6, 6, 3, 3, 3, 3, 7, 8, 8, 8, 8, 8, 8, 6, 8, 7, 7, 7, 7, 9, 7, 6, 6, 6, 6, 6, 6, 6, 9, 5, 6, 6, 6, 6, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 } }, { 1292, 13, 14, 3, 11, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 8, 7, 12, 9, 4, 6, 6, 6, 7, 4, 8, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 7, 7, 7, 8, 12, 8, 9, 8, 9, 8, 7, 10, 9, 4, 7, 9, 7, 11, 9, 10, 8, 10, 9, 9, 8, 9, 8, 10, 8, 8, 7, 4, 4, 4, 7, 7, 4, 7, 7, 7, 7, 7, 5, 7, 7, 3, 3, 7, 3, 11, 7, 7, 7, 7, 5, 7, 5, 7, 8, 11, 7, 8, 6, 5, 4, 5, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 7, 7, 7, 4, 7, 5, 11, 6, 8, 8, 5, 11, 4, 5, 7, 4, 4, 4, 7, 7, 4, 4, 4, 6, 8, 10, 10, 10, 8, 8, 8, 8, 8, 8, 8, 13, 8, 8, 8, 8, 8, 4, 4, 4, 4, 9, 9, 10, 10, 10, 10, 10, 7, 10, 9, 9, 9, 9, 8, 8, 8, 7, 7, 7, 7, 7, 7, 11, 7, 7, 7, 7, 7, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8 } }, { 1294, 15, 16, 3, 13, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 9, 8, 13, 11, 5, 5, 5, 6, 9, 4, 9, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 5, 8, 9, 8, 9, 14, 10, 10, 11, 11, 9, 9, 11, 10, 4, 8, 10, 8, 13, 11, 12, 10, 12, 11, 10, 8, 11, 10, 14, 9, 10, 9, 5, 4, 5, 8, 8, 5, 8, 9, 8, 9, 8, 4, 9, 9, 4, 4, 8, 4, 12, 9, 9, 9, 9, 6, 8, 5, 9, 8, 10, 7, 8, 6, 6, 4, 6, 9, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 9, 4, 8, 5, 12, 6, 9, 9, 5, 12, 5, 6, 9, 5, 5, 5, 9, 8, 4, 5, 4, 6, 9, 12, 12, 12, 9, 10, 10, 10, 10, 10, 10, 15, 11, 9, 9, 9, 9, 4, 4, 4, 4, 11, 11, 12, 12, 12, 12, 12, 9, 12, 11, 11, 11, 11, 10, 10, 8, 8, 8, 8, 8, 8, 8, 13, 9, 8, 8, 8, 8, 4, 4, 4, 4, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 9, 8 } }, { 1298, 18, 21, 5, 16, { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 11, 10, 16, 14, 5, 7, 7, 9, 11, 5, 11, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 6, 6, 11, 10, 11, 10, 18, 13, 13, 14, 14, 12, 12, 14, 13, 5, 10, 14, 11, 16, 14, 16, 12, 16, 13, 12, 11, 13, 13, 17, 12, 13, 11, 6, 5, 6, 10, 10, 5, 10, 12, 10, 12, 11, 7, 12, 11, 5, 5, 10, 5, 15, 11, 12, 12, 12, 7, 10, 6, 11, 9, 13, 9, 9, 10, 8, 5, 8, 11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 10, 11, 11, 10, 5, 10, 7, 15, 8, 11, 11, 7, 15, 7, 7, 11, 6, 6, 5, 11, 10, 4, 7, 6, 8, 11, 15, 15, 15, 10, 13, 13, 13, 13, 13, 13, 18, 14, 12, 12, 12, 12, 5, 5, 5, 5, 14, 14, 16, 16, 16, 16, 16, 11, 16, 13, 13, 13, 13, 13, 12, 10, 10, 10, 10, 10, 10, 10, 16, 10, 11, 11, 11, 11, 5, 5, 5, 5, 12, 11, 12, 12, 12, 12, 12, 11, 12, 11, 11, 11, 11, 9, 12, 9 } }, { 1304, 24, 27, 5, 22, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 9, 14, 13, 22, 18, 7, 8, 8, 10, 15, 7, 15, 7, 8, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 7, 7, 15, 14, 14, 15, 24, 18, 18, 18, 19, 16, 15, 19, 19, 7, 14, 18, 15, 23, 19, 19, 17, 19, 17, 17, 15, 19, 18, 23, 18, 17, 16, 8, 8, 8, 14, 14, 7, 14, 15, 13, 15, 14, 9, 15, 15, 7, 7, 14, 7, 21, 15, 14, 15, 15, 10, 13, 9, 15, 14, 19, 13, 15, 13, 10, 7, 10, 14, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 14, 14, 14, 14, 7, 14, 9, 19, 10, 13, 15, 8, 19, 9, 9, 15, 7, 7, 8, 15, 13, 7, 8, 7, 10, 13, 19, 19, 19, 15, 18, 18, 18, 18, 18, 18, 24, 18, 16, 16, 16, 16, 7, 7, 7, 7, 19, 19, 19, 19, 19, 19, 19, 15, 19, 19, 19, 19, 19, 17, 17, 14, 14, 14, 14, 14, 14, 14, 22, 13, 14, 14, 14, 14, 7, 7, 7, 7, 14, 15, 14, 14, 14, 14, 14, 15, 14, 15, 15, 15, 15, 15, 15, 15 } }, { 1544, 9, 10, 2, 8, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 6, 5, 7, 6, 2, 3, 3, 3, 5, 2, 6, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 6, 5, 5, 9, 6, 6, 6, 6, 6, 5, 6, 6, 2, 4, 6, 4, 7, 6, 6, 6, 6, 6, 6, 4, 6, 6, 8, 6, 6, 6, 3, 2, 3, 5, 5, 2, 4, 4, 4, 4, 4, 3, 4, 5, 2, 2, 4, 2, 6, 5, 5, 4, 4, 3, 4, 3, 4, 5, 6, 5, 4, 4, 3, 2, 3, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 6, 5, 5, 5, 2, 5, 2, 8, 4, 6, 6, 5, 8, 2, 3, 5, 2, 2, 2, 4, 5, 2, 2, 2, 4, 6, 7, 7, 7, 5, 6, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 5, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4 } }, { 1546, 11, 12, 2, 10, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 7, 6, 9, 8, 3, 4, 4, 4, 6, 3, 7, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 6, 7, 6, 6, 11, 7, 7, 8, 8, 7, 6, 8, 8, 3, 5, 7, 5, 9, 8, 8, 7, 8, 7, 7, 5, 8, 7, 10, 7, 7, 7, 4, 3, 4, 6, 6, 3, 5, 5, 5, 5, 5, 4, 5, 6, 2, 2, 5, 2, 8, 6, 6, 5, 5, 4, 5, 4, 5, 6, 8, 6, 5, 5, 4, 3, 4, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 7, 6, 6, 6, 3, 6, 3, 10, 5, 8, 7, 6, 10, 3, 4, 6, 3, 3, 3, 5, 6, 3, 3, 3, 5, 8, 9, 9, 9, 6, 7, 7, 7, 7, 7, 7, 10, 8, 7, 7, 7, 7, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 6, 8, 8, 8, 8, 8, 7, 7, 6, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 5, 5, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5 } }, { 1548, 12, 14, 3, 11, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 5, 7, 7, 11, 9, 3, 4, 4, 5, 7, 3, 8, 3, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 8, 7, 8, 7, 12, 9, 8, 8, 9, 8, 8, 8, 10, 4, 8, 8, 7, 12, 10, 9, 8, 9, 8, 8, 7, 9, 8, 11, 9, 8, 9, 4, 4, 4, 6, 7, 3, 7, 7, 6, 7, 6, 3, 7, 7, 3, 3, 6, 3, 9, 7, 7, 7, 7, 4, 6, 4, 7, 6, 9, 6, 6, 6, 5, 4, 5, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 7, 7, 4, 7, 3, 11, 5, 7, 8, 5, 11, 4, 5, 7, 4, 4, 2, 7, 8, 3, 3, 4, 5, 7, 10, 10, 10, 7, 9, 9, 9, 9, 9, 9, 11, 8, 8, 8, 8, 8, 4, 4, 4, 4, 9, 10, 9, 9, 9, 9, 9, 7, 10, 9, 9, 9, 9, 8, 8, 7, 7, 7, 7, 7, 7, 7, 11, 6, 6, 6, 6, 6, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7 } }, { 1550, 15, 16, 3, 13, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 9, 8, 12, 10, 3, 5, 5, 8, 9, 3, 9, 3, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 9, 9, 9, 8, 13, 11, 10, 10, 10, 9, 9, 11, 11, 5, 9, 10, 8, 14, 11, 11, 9, 11, 10, 9, 8, 11, 11, 14, 10, 9, 9, 5, 6, 5, 7, 8, 3, 8, 8, 7, 8, 8, 4, 8, 8, 4, 3, 7, 3, 11, 8, 8, 8, 8, 5, 7, 4, 8, 7, 10, 7, 7, 7, 5, 3, 5, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 9, 8, 9, 3, 8, 5, 12, 5, 8, 9, 6, 12, 4, 6, 9, 5, 5, 4, 8, 8, 4, 3, 5, 5, 8, 12, 12, 12, 8, 11, 11, 11, 11, 11, 11, 15, 10, 9, 9, 9, 9, 5, 5, 5, 5, 10, 11, 11, 11, 11, 11, 11, 9, 11, 11, 11, 11, 11, 9, 9, 8, 8, 8, 8, 8, 8, 8, 12, 7, 8, 8, 8, 8, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 7, 8, 7 } }, { 1554, 18, 21, 5, 16, { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 11, 10, 16, 12, 4, 6, 6, 8, 10, 5, 11, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 5, 5, 11, 11, 11, 10, 18, 12, 13, 13, 13, 12, 11, 14, 14, 6, 9, 13, 10, 15, 14, 15, 12, 15, 14, 12, 11, 14, 12, 17, 12, 12, 11, 5, 5, 5, 10, 10, 4, 10, 11, 9, 11, 9, 5, 10, 11, 4, 4, 9, 4, 14, 11, 10, 11, 10, 7, 9, 5, 10, 9, 13, 10, 10, 9, 6, 4, 7, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 10, 10, 11, 10, 4, 10, 6, 15, 7, 10, 11, 7, 15, 5, 7, 10, 6, 6, 4, 10, 10, 4, 5, 6, 7, 10, 15, 15, 15, 9, 12, 12, 12, 12, 12, 12, 17, 13, 12, 12, 12, 12, 6, 6, 6, 6, 13, 14, 15, 15, 15, 15, 15, 10, 15, 14, 14, 14, 14, 12, 12, 10, 10, 10, 10, 10, 10, 10, 15, 9, 9, 9, 9, 9, 4, 4, 4, 4, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 10 } }, { 1560, 23, 27, 5, 22, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8, 14, 13, 22, 17, 6, 8, 8, 10, 14, 6, 15, 6, 7, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 15, 15, 14, 13, 22, 17, 17, 18, 18, 16, 14, 19, 18, 8, 13, 18, 14, 22, 18, 18, 16, 18, 17, 16, 16, 18, 17, 22, 17, 16, 15, 7, 7, 7, 12, 14, 6, 13, 14, 12, 14, 13, 8, 14, 13, 6, 6, 12, 6, 20, 14, 13, 14, 14, 9, 12, 8, 14, 13, 18, 12, 13, 12, 9, 6, 9, 14, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 13, 14, 13, 14, 6, 13, 8, 19, 9, 14, 15, 8, 19, 8, 9, 14, 7, 7, 7, 14, 12, 6, 7, 7, 9, 14, 19, 19, 19, 13, 17, 17, 17, 17, 17, 17, 23, 18, 16, 16, 16, 16, 8, 8, 8, 8, 18, 18, 18, 18, 18, 18, 18, 14, 18, 18, 18, 18, 18, 16, 16, 15, 13, 13, 13, 13, 13, 13, 21, 12, 13, 13, 13, 13, 6, 6, 6, 6, 13, 14, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 13, 14, 13 } }, { 1800, 8, 10, 2, 8, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 5, 6, 5, 7, 6, 2, 4, 4, 5, 5, 2, 6, 2, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 6, 5, 8, 6, 6, 6, 6, 5, 4, 6, 6, 2, 5, 6, 5, 8, 6, 6, 6, 6, 6, 6, 5, 6, 6, 8, 6, 6, 6, 3, 4, 3, 5, 5, 3, 5, 5, 4, 5, 5, 2, 5, 5, 2, 2, 5, 2, 7, 5, 5, 5, 5, 3, 5, 3, 5, 5, 6, 4, 5, 4, 4, 3, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 6, 6, 5, 6, 3, 6, 3, 8, 4, 6, 6, 4, 8, 3, 3, 5, 2, 2, 2, 5, 6, 2, 2, 2, 4, 6, 7, 7, 7, 5, 6, 6, 6, 6, 6, 6, 8, 6, 5, 5, 5, 5, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 7, 4, 5, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 } }, { 1802, 10, 12, 2, 10, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 6, 7, 6, 9, 8, 3, 5, 5, 6, 6, 3, 7, 3, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 6, 6, 7, 6, 10, 8, 7, 7, 8, 6, 5, 8, 7, 3, 6, 8, 6, 10, 8, 8, 7, 8, 8, 7, 6, 7, 8, 10, 7, 7, 7, 4, 5, 4, 6, 6, 4, 6, 6, 5, 6, 6, 3, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 6, 4, 6, 6, 8, 5, 6, 5, 5, 4, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 7, 7, 6, 7, 4, 7, 4, 10, 5, 8, 7, 5, 10, 4, 4, 6, 3, 3, 3, 6, 7, 3, 3, 3, 5, 8, 9, 9, 9, 6, 8, 8, 8, 8, 8, 8, 10, 7, 6, 6, 6, 6, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 6, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 9, 5, 6, 6, 6, 6, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 6 } }, { 1804, 13, 14, 3, 11, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 7, 13, 9, 4, 5, 5, 6, 8, 3, 8, 3, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 7, 7, 7, 8, 11, 8, 9, 8, 9, 8, 7, 9, 10, 5, 7, 9, 7, 12, 10, 9, 8, 9, 9, 8, 7, 8, 9, 10, 9, 7, 7, 4, 5, 4, 6, 7, 4, 6, 7, 7, 7, 7, 5, 7, 7, 3, 3, 7, 3, 11, 7, 7, 7, 7, 5, 7, 5, 7, 7, 10, 7, 7, 6, 5, 4, 5, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 7, 7, 7, 4, 7, 5, 11, 6, 10, 8, 5, 11, 4, 5, 8, 4, 4, 4, 7, 7, 4, 4, 4, 6, 10, 10, 10, 10, 7, 8, 8, 8, 8, 8, 8, 11, 8, 8, 8, 8, 8, 5, 5, 5, 5, 9, 10, 9, 9, 9, 9, 9, 8, 9, 8, 8, 8, 8, 7, 8, 7, 6, 6, 6, 6, 6, 6, 10, 7, 7, 7, 7, 7, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7 } }, { 1806, 14, 16, 3, 13, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 7, 10, 8, 13, 11, 5, 5, 6, 6, 9, 4, 9, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 5, 8, 9, 9, 9, 14, 9, 10, 11, 11, 9, 8, 11, 10, 4, 8, 10, 8, 13, 11, 12, 10, 12, 10, 10, 8, 11, 10, 14, 9, 10, 9, 5, 6, 5, 8, 8, 5, 8, 9, 8, 9, 8, 5, 9, 9, 4, 4, 8, 4, 12, 9, 8, 9, 9, 6, 8, 5, 9, 8, 11, 7, 7, 6, 6, 4, 6, 9, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 8, 9, 9, 9, 4, 9, 5, 12, 6, 11, 9, 5, 12, 5, 6, 9, 5, 5, 5, 9, 8, 4, 5, 5, 6, 11, 12, 12, 13, 8, 9, 9, 9, 9, 9, 9, 14, 11, 9, 9, 9, 9, 4, 4, 4, 4, 11, 11, 12, 12, 12, 12, 12, 9, 12, 11, 11, 11, 11, 10, 10, 9, 8, 8, 8, 8, 8, 8, 13, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 9, 8, 8, 8, 8, 8, 9, 8, 9, 9, 9, 9, 7, 9, 7 } }, { 1810, 19, 21, 5, 16, { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 9, 12, 10, 16, 14, 6, 7, 8, 9, 11, 5, 11, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 6, 6, 11, 11, 11, 11, 18, 13, 13, 14, 14, 12, 11, 14, 13, 5, 10, 14, 10, 17, 14, 15, 12, 16, 13, 12, 11, 13, 13, 18, 12, 13, 11, 6, 5, 6, 11, 10, 6, 10, 11, 10, 11, 10, 7, 11, 11, 5, 5, 10, 5, 15, 11, 10, 11, 11, 7, 10, 7, 11, 9, 14, 10, 9, 9, 8, 5, 9, 11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 12, 11, 11, 10, 5, 10, 7, 15, 8, 14, 11, 9, 15, 7, 7, 11, 6, 6, 5, 11, 10, 4, 7, 6, 8, 14, 15, 15, 15, 11, 13, 13, 13, 13, 13, 13, 19, 14, 12, 12, 12, 12, 5, 5, 5, 5, 14, 14, 15, 15, 15, 15, 15, 11, 16, 13, 13, 13, 13, 13, 12, 10, 10, 10, 10, 10, 10, 10, 15, 9, 10, 10, 10, 10, 5, 5, 5, 5, 10, 11, 11, 11, 11, 11, 11, 11, 10, 11, 11, 11, 11, 9, 11, 9 } }, { 1816, 24, 27, 5, 22, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 9, 14, 13, 22, 18, 7, 8, 8, 10, 15, 7, 15, 7, 8, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 8, 15, 14, 15, 15, 24, 18, 18, 18, 19, 16, 15, 19, 19, 7, 14, 18, 15, 23, 19, 19, 17, 19, 17, 17, 15, 19, 18, 23, 18, 17, 16, 8, 8, 8, 14, 14, 7, 14, 15, 13, 15, 14, 9, 15, 15, 7, 7, 14, 7, 21, 15, 14, 15, 15, 10, 13, 9, 15, 14, 19, 13, 14, 13, 10, 7, 10, 14, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 14, 14, 14, 14, 7, 14, 10, 19, 10, 13, 15, 10, 19, 9, 9, 15, 7, 7, 8, 15, 13, 7, 9, 7, 10, 13, 19, 19, 19, 15, 18, 18, 18, 18, 18, 18, 24, 18, 16, 16, 16, 16, 7, 7, 7, 7, 19, 19, 19, 19, 19, 19, 19, 15, 19, 19, 19, 19, 19, 17, 17, 14, 14, 14, 14, 14, 14, 14, 22, 13, 14, 14, 14, 14, 7, 7, 7, 7, 14, 15, 14, 14, 14, 14, 14, 15, 14, 15, 15, 15, 15, 14, 15, 15 } }, { 2056, 8, 9, 2, 7, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 6, 6, 2, 3, 3, 4, 5, 2, 6, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 5, 4, 3, 7, 6, 5, 6, 6, 5, 5, 6, 6, 3, 3, 6, 5, 8, 6, 6, 5, 6, 6, 5, 5, 6, 6, 8, 6, 6, 5, 2, 2, 2, 4, 4, 2, 3, 4, 4, 4, 4, 3, 4, 4, 2, 2, 4, 3, 6, 4, 4, 4, 4, 3, 3, 3, 4, 4, 6, 5, 4, 4, 3, 2, 3, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 6, 2, 4, 4, 7, 3, 4, 6, 3, 7, 3, 3, 5, 2, 2, 2, 4, 5, 2, 3, 2, 3, 4, 6, 6, 6, 3, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 5, 4, 3, 3, 3, 3, 3, 3, 6, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 } }, { 2058, 10, 12, 3, 9, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 5, 8, 8, 3, 4, 4, 5, 6, 3, 7, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 5, 6, 5, 4, 9, 8, 6, 7, 7, 6, 6, 7, 8, 4, 4, 7, 6, 10, 8, 7, 6, 7, 7, 5, 6, 8, 8, 10, 8, 8, 6, 3, 3, 3, 5, 5, 3, 4, 5, 4, 5, 4, 4, 5, 5, 3, 3, 5, 4, 8, 5, 5, 5, 5, 4, 4, 4, 5, 5, 8, 6, 5, 5, 4, 2, 4, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 5, 5, 5, 5, 2, 5, 5, 9, 4, 5, 7, 4, 9, 4, 4, 6, 3, 3, 3, 5, 6, 2, 4, 3, 4, 5, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8, 9, 7, 6, 6, 6, 6, 4, 4, 4, 4, 7, 8, 7, 7, 7, 7, 7, 6, 8, 8, 8, 8, 8, 8, 6, 5, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5 } }, { 2060, 12, 14, 3, 11, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, 6, 10, 10, 4, 5, 5, 6, 7, 3, 7, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 7, 7, 7, 5, 11, 9, 8, 8, 9, 8, 7, 9, 9, 4, 5, 9, 7, 11, 9, 9, 7, 9, 8, 7, 7, 9, 9, 12, 9, 9, 8, 4, 3, 4, 6, 6, 4, 6, 6, 6, 6, 6, 4, 6, 6, 3, 3, 6, 3, 9, 6, 6, 6, 6, 4, 6, 4, 6, 6, 9, 6, 6, 6, 6, 3, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 6, 6, 7, 6, 3, 6, 3, 10, 5, 7, 8, 4, 11, 4, 5, 7, 4, 4, 4, 6, 7, 3, 3, 4, 5, 7, 9, 9, 9, 5, 9, 9, 9, 9, 9, 9, 11, 8, 8, 8, 8, 8, 4, 4, 4, 4, 9, 9, 9, 9, 9, 9, 9, 7, 9, 8, 8, 8, 8, 9, 7, 6, 6, 6, 6, 6, 6, 6, 9, 5, 6, 6, 6, 6, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6 } }, { 2062, 13, 15, 3, 12, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, 7, 7, 12, 11, 4, 5, 5, 7, 8, 3, 9, 3, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 8, 8, 8, 6, 13, 11, 9, 10, 10, 9, 8, 11, 10, 5, 6, 10, 9, 13, 11, 10, 8, 10, 9, 8, 9, 10, 9, 13, 10, 9, 8, 5, 4, 5, 7, 7, 4, 7, 7, 7, 7, 7, 4, 7, 7, 3, 4, 7, 3, 11, 7, 7, 7, 7, 5, 6, 4, 7, 7, 11, 7, 7, 6, 7, 3, 7, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 8, 7, 7, 3, 7, 5, 12, 4, 7, 9, 5, 12, 4, 6, 8, 4, 4, 5, 7, 7, 4, 5, 4, 5, 7, 10, 10, 10, 6, 11, 11, 11, 11, 11, 11, 13, 10, 9, 9, 9, 9, 5, 5, 5, 5, 10, 11, 10, 10, 10, 10, 10, 8, 10, 10, 10, 10, 10, 9, 8, 7, 7, 7, 7, 7, 7, 7, 11, 7, 7, 7, 7, 7, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7 } }, { 2066, 18, 19, 4, 15, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 10, 9, 15, 14, 5, 7, 7, 9, 10, 4, 10, 4, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 4, 11, 10, 11, 8, 17, 15, 12, 12, 13, 11, 11, 14, 13, 6, 7, 13, 11, 16, 13, 14, 10, 14, 12, 10, 12, 13, 13, 18, 12, 12, 12, 6, 5, 6, 9, 9, 5, 8, 9, 8, 9, 8, 6, 8, 10, 5, 5, 9, 5, 15, 10, 9, 9, 9, 7, 7, 6, 9, 9, 12, 9, 8, 8, 9, 3, 9, 11, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 11, 11, 9, 3, 10, 5, 15, 5, 10, 11, 6, 15, 5, 7, 10, 5, 5, 4, 9, 8, 4, 6, 5, 6, 10, 13, 13, 13, 8, 15, 15, 15, 15, 15, 15, 17, 12, 11, 11, 11, 11, 6, 6, 6, 6, 13, 13, 14, 14, 14, 14, 14, 10, 14, 13, 13, 13, 13, 12, 10, 9, 9, 9, 9, 9, 9, 9, 12, 8, 8, 8, 8, 8, 5, 5, 5, 5, 9, 10, 9, 9, 9, 9, 9, 10, 9, 9, 9, 9, 9, 8, 9, 8 } }, { 2072, 23, 26, 6, 20, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 10, 13, 12, 19, 18, 8, 8, 8, 12, 14, 7, 14, 6, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 6, 7, 13, 14, 13, 11, 22, 17, 16, 16, 17, 15, 14, 18, 19, 8, 11, 17, 14, 22, 18, 18, 15, 18, 16, 13, 16, 18, 17, 23, 18, 16, 15, 8, 7, 8, 11, 13, 7, 11, 12, 11, 12, 11, 7, 12, 13, 6, 6, 12, 6, 20, 13, 12, 12, 12, 8, 10, 7, 13, 11, 17, 13, 11, 10, 10, 6, 10, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 12, 12, 13, 14, 6, 12, 8, 19, 8, 13, 14, 9, 19, 8, 9, 14, 7, 7, 8, 13, 11, 6, 8, 7, 8, 12, 18, 18, 18, 11, 17, 17, 17, 17, 17, 17, 21, 16, 15, 15, 15, 15, 8, 8, 8, 8, 17, 18, 18, 18, 18, 18, 18, 14, 18, 18, 18, 18, 18, 16, 15, 12, 11, 11, 11, 11, 11, 11, 16, 11, 11, 11, 11, 11, 6, 6, 6, 6, 12, 13, 12, 12, 12, 12, 12, 14, 12, 13, 13, 13, 13, 11, 12, 11 } }, { 2312, 9, 9, 2, 7, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 4, 7, 7, 3, 2, 3, 5, 5, 3, 5, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 5, 5, 5, 5, 9, 6, 6, 6, 6, 6, 6, 6, 7, 4, 4, 6, 6, 8, 6, 6, 5, 6, 6, 5, 6, 6, 6, 8, 6, 6, 6, 3, 2, 3, 5, 4, 3, 4, 4, 4, 5, 4, 2, 4, 4, 2, 3, 4, 2, 6, 5, 5, 4, 4, 3, 3, 3, 4, 4, 5, 4, 4, 4, 3, 2, 3, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 5, 5, 5, 6, 2, 4, 3, 7, 3, 5, 6, 3, 7, 3, 3, 5, 2, 2, 3, 4, 5, 2, 2, 2, 3, 5, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 5, 5, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4 } }, { 2314, 11, 12, 3, 9, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 5, 6, 5, 9, 9, 4, 4, 4, 6, 6, 4, 7, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 6, 6, 6, 6, 11, 7, 7, 7, 8, 7, 7, 7, 9, 5, 5, 8, 7, 10, 8, 7, 6, 7, 7, 6, 7, 7, 8, 10, 7, 8, 7, 4, 3, 4, 6, 5, 4, 5, 5, 5, 6, 5, 3, 5, 5, 3, 4, 5, 3, 8, 6, 6, 5, 5, 4, 4, 4, 5, 5, 6, 5, 5, 5, 4, 3, 4, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 6, 3, 5, 4, 9, 4, 6, 7, 3, 9, 4, 4, 6, 3, 3, 4, 5, 6, 3, 3, 3, 4, 6, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 9, 7, 7, 7, 7, 7, 5, 5, 5, 5, 8, 8, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 8, 6, 6, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 5, 5, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5 } }, { 2316, 13, 14, 3, 11, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 6, 12, 10, 4, 4, 4, 6, 7, 4, 7, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 7, 7, 8, 7, 12, 9, 9, 8, 9, 8, 8, 9, 10, 5, 7, 10, 8, 11, 9, 9, 8, 9, 9, 7, 9, 9, 9, 12, 9, 9, 8, 4, 3, 4, 7, 6, 4, 7, 6, 6, 6, 7, 4, 6, 6, 3, 3, 7, 3, 9, 6, 7, 6, 6, 5, 6, 4, 6, 6, 9, 6, 6, 6, 5, 3, 5, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 6, 6, 7, 8, 3, 6, 4, 11, 4, 8, 8, 4, 11, 4, 5, 7, 4, 4, 4, 6, 8, 3, 4, 4, 4, 8, 9, 9, 9, 7, 9, 9, 9, 9, 9, 9, 13, 8, 8, 8, 8, 8, 5, 5, 5, 5, 9, 9, 9, 9, 9, 9, 9, 7, 9, 9, 9, 9, 9, 9, 8, 8, 7, 7, 7, 7, 7, 7, 8, 6, 7, 7, 7, 7, 3, 3, 3, 3, 7, 6, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6 } }, { 2318, 15, 15, 3, 12, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 7, 7, 14, 12, 4, 5, 5, 7, 8, 3, 8, 4, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 8, 8, 8, 7, 14, 10, 10, 10, 11, 10, 10, 10, 12, 6, 7, 11, 9, 13, 10, 11, 9, 11, 11, 9, 10, 9, 10, 15, 10, 10, 9, 5, 4, 5, 8, 7, 4, 7, 8, 7, 7, 7, 5, 7, 8, 4, 4, 8, 5, 12, 8, 7, 8, 7, 6, 6, 5, 7, 8, 9, 7, 7, 7, 7, 3, 7, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 8, 8, 8, 3, 7, 5, 12, 5, 9, 8, 5, 12, 5, 6, 8, 4, 4, 5, 7, 8, 4, 5, 4, 5, 9, 10, 10, 10, 7, 10, 10, 10, 10, 10, 10, 14, 10, 10, 10, 10, 10, 6, 6, 6, 6, 11, 10, 11, 11, 11, 11, 11, 8, 11, 9, 9, 9, 9, 10, 9, 8, 7, 7, 7, 7, 7, 7, 11, 7, 7, 7, 7, 7, 4, 4, 4, 4, 7, 8, 7, 7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 7, 8, 7 } }, { 2322, 19, 19, 4, 15, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 10, 9, 9, 18, 16, 6, 6, 6, 9, 11, 5, 11, 5, 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 11, 11, 11, 9, 17, 13, 12, 13, 14, 12, 11, 15, 15, 7, 9, 15, 12, 17, 14, 15, 11, 15, 13, 11, 12, 13, 14, 18, 13, 13, 12, 6, 5, 6, 11, 9, 6, 9, 9, 8, 10, 8, 6, 9, 11, 5, 5, 10, 6, 16, 11, 9, 10, 9, 8, 7, 7, 11, 9, 12, 9, 9, 8, 8, 4, 8, 10, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 9, 9, 9, 9, 4, 9, 6, 15, 6, 11, 11, 6, 15, 6, 7, 11, 5, 5, 6, 11, 10, 5, 6, 5, 6, 11, 13, 13, 13, 9, 13, 13, 13, 13, 13, 13, 19, 13, 12, 12, 12, 12, 7, 7, 7, 7, 14, 14, 15, 15, 15, 15, 15, 11, 15, 13, 13, 13, 13, 13, 11, 10, 9, 9, 9, 9, 9, 9, 13, 8, 8, 8, 8, 8, 5, 5, 5, 5, 9, 11, 9, 9, 9, 9, 9, 11, 9, 11, 11, 11, 11, 9, 10, 9 } }, { 2328, 25, 26, 6, 20, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 12, 13, 12, 19, 21, 8, 8, 8, 13, 14, 6, 15, 6, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 8, 8, 14, 14, 14, 12, 23, 18, 16, 18, 18, 17, 15, 19, 19, 10, 12, 19, 16, 24, 18, 19, 15, 19, 18, 14, 16, 18, 18, 25, 18, 18, 17, 8, 7, 8, 15, 13, 8, 12, 13, 11, 14, 11, 8, 12, 14, 7, 8, 15, 7, 21, 14, 13, 14, 14, 11, 10, 8, 14, 12, 18, 12, 12, 11, 10, 6, 10, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 13, 13, 13, 13, 6, 11, 8, 19, 8, 13, 15, 8, 19, 8, 9, 14, 7, 7, 8, 14, 14, 6, 8, 7, 8, 13, 18, 18, 18, 12, 18, 18, 18, 18, 18, 18, 25, 18, 17, 17, 17, 17, 10, 10, 10, 10, 18, 18, 19, 19, 19, 19, 19, 14, 19, 18, 18, 18, 18, 18, 15, 14, 12, 12, 12, 12, 12, 12, 17, 11, 11, 11, 11, 11, 7, 7, 7, 7, 13, 14, 13, 13, 13, 13, 13, 14, 13, 14, 14, 14, 14, 12, 14, 12 } }, { 2568, 8, 9, 2, 7, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 7, 6, 2, 2, 3, 4, 6, 2, 6, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 6, 4, 4, 8, 6, 5, 6, 6, 5, 5, 6, 6, 2, 3, 6, 5, 8, 6, 6, 5, 6, 5, 4, 5, 6, 5, 7, 5, 5, 5, 3, 4, 3, 4, 4, 2, 4, 4, 4, 4, 4, 2, 3, 4, 2, 2, 4, 2, 6, 4, 4, 4, 4, 4, 3, 2, 4, 4, 6, 3, 4, 3, 3, 2, 3, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 5, 2, 4, 2, 7, 3, 4, 6, 3, 7, 2, 3, 6, 2, 2, 2, 4, 5, 2, 2, 2, 2, 4, 6, 6, 6, 4, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4 } }, { 2570, 10, 12, 3, 9, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 5, 9, 8, 3, 3, 4, 5, 7, 3, 7, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 5, 7, 5, 5, 10, 7, 6, 7, 7, 6, 6, 8, 7, 3, 4, 7, 6, 10, 7, 7, 6, 7, 6, 5, 6, 7, 6, 9, 6, 6, 6, 4, 5, 4, 5, 5, 3, 5, 5, 5, 5, 5, 3, 4, 5, 3, 3, 5, 3, 7, 5, 5, 5, 5, 4, 4, 3, 5, 5, 7, 4, 5, 4, 4, 3, 4, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 5, 5, 5, 7, 3, 5, 3, 9, 4, 5, 7, 4, 9, 3, 4, 7, 3, 3, 3, 5, 6, 3, 3, 3, 3, 5, 7, 7, 7, 5, 7, 7, 7, 7, 7, 7, 8, 7, 6, 6, 6, 6, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5 } }, { 2572, 12, 14, 3, 11, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 6, 10, 9, 4, 4, 4, 6, 8, 3, 8, 3, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 8, 8, 8, 6, 12, 8, 8, 7, 9, 8, 8, 8, 9, 5, 5, 8, 7, 11, 9, 7, 8, 7, 8, 6, 7, 8, 7, 10, 8, 7, 7, 5, 3, 5, 5, 6, 4, 6, 6, 5, 6, 6, 4, 5, 6, 4, 4, 6, 3, 9, 6, 6, 6, 6, 4, 5, 4, 6, 6, 9, 6, 6, 5, 5, 4, 5, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, 6, 7, 6, 4, 6, 4, 11, 4, 6, 8, 4, 11, 4, 5, 8, 4, 4, 4, 6, 7, 3, 4, 3, 4, 6, 9, 9, 9, 6, 8, 8, 8, 8, 8, 8, 11, 7, 8, 8, 8, 8, 5, 5, 5, 5, 9, 9, 7, 7, 7, 7, 7, 8, 7, 8, 8, 8, 8, 7, 8, 6, 7, 7, 7, 7, 7, 7, 9, 5, 6, 6, 6, 6, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6 } }, { 2574, 13, 15, 3, 12, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, 7, 7, 12, 11, 5, 5, 5, 7, 10, 4, 9, 3, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 10, 10, 10, 7, 13, 9, 8, 9, 10, 9, 9, 10, 10, 5, 6, 10, 8, 12, 11, 10, 9, 10, 9, 7, 8, 10, 9, 11, 9, 8, 8, 6, 4, 6, 6, 7, 5, 7, 7, 6, 7, 7, 5, 6, 7, 4, 4, 7, 4, 10, 7, 7, 7, 7, 5, 6, 5, 7, 6, 9, 7, 7, 6, 6, 4, 6, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 7, 7, 7, 7, 4, 7, 5, 12, 5, 7, 9, 5, 12, 5, 6, 10, 4, 4, 4, 7, 8, 4, 5, 4, 5, 7, 10, 10, 10, 7, 9, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 5, 5, 5, 5, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, 9, 7, 7, 7, 7, 7, 7, 7, 10, 6, 7, 7, 7, 7, 4, 4, 4, 4, 7, 7, 7, 7, 7, 7, 7, 10, 7, 7, 7, 7, 7, 7, 7, 7 } }, { 2578, 17, 19, 4, 15, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 8, 9, 9, 15, 14, 6, 6, 6, 9, 13, 4, 11, 4, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 6, 13, 13, 13, 9, 17, 11, 12, 12, 14, 11, 11, 14, 13, 6, 7, 13, 10, 16, 12, 14, 11, 14, 12, 9, 10, 14, 11, 15, 11, 11, 10, 7, 5, 7, 8, 9, 6, 10, 9, 8, 10, 8, 5, 8, 10, 5, 5, 8, 5, 15, 10, 9, 9, 9, 6, 8, 5, 9, 8, 13, 8, 8, 7, 8, 5, 8, 10, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 9, 10, 9, 9, 5, 9, 6, 15, 5, 10, 11, 6, 15, 6, 7, 13, 5, 5, 6, 9, 10, 5, 6, 5, 6, 10, 13, 13, 13, 9, 11, 11, 11, 11, 11, 11, 16, 12, 11, 11, 11, 11, 6, 6, 6, 6, 14, 12, 14, 14, 14, 14, 14, 13, 14, 14, 14, 14, 14, 11, 11, 9, 10, 10, 10, 10, 10, 10, 13, 8, 8, 8, 8, 8, 5, 5, 5, 5, 9, 10, 9, 9, 9, 9, 9, 13, 9, 9, 9, 9, 9, 8, 9, 8 } }, { 2584, 23, 25, 5, 20, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 11, 13, 12, 20, 19, 7, 8, 8, 13, 17, 6, 17, 6, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 8, 8, 17, 17, 17, 12, 23, 15, 15, 16, 18, 15, 15, 18, 18, 8, 11, 16, 14, 20, 16, 18, 15, 18, 15, 12, 14, 18, 15, 21, 15, 14, 14, 10, 7, 10, 11, 13, 7, 13, 12, 11, 13, 10, 7, 12, 13, 7, 6, 11, 6, 20, 13, 12, 12, 12, 9, 9, 7, 12, 12, 17, 11, 11, 10, 10, 6, 10, 14, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 13, 13, 13, 13, 6, 13, 8, 19, 8, 13, 17, 8, 19, 8, 9, 17, 7, 7, 8, 12, 13, 6, 8, 7, 8, 13, 18, 18, 18, 12, 15, 15, 15, 15, 15, 15, 22, 16, 15, 15, 15, 15, 8, 8, 8, 8, 18, 16, 18, 18, 18, 18, 18, 17, 18, 18, 18, 18, 18, 14, 15, 13, 13, 13, 13, 13, 13, 13, 16, 11, 10, 10, 10, 10, 7, 7, 7, 7, 12, 13, 12, 12, 12, 12, 12, 17, 12, 12, 12, 12, 12, 11, 12, 11 } }, { 2824, 9, 9, 2, 7, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 6, 4, 9, 6, 3, 5, 5, 6, 6, 3, 6, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 5, 6, 5, 4, 9, 5, 6, 5, 6, 6, 6, 6, 6, 3, 4, 6, 5, 8, 6, 6, 5, 6, 6, 5, 5, 6, 6, 7, 6, 5, 5, 4, 4, 4, 6, 4, 3, 4, 4, 4, 4, 4, 3, 3, 4, 2, 2, 4, 2, 6, 4, 4, 4, 4, 3, 3, 3, 4, 3, 6, 3, 4, 3, 4, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 6, 4, 2, 4, 4, 7, 4, 6, 6, 2, 7, 3, 3, 6, 2, 2, 3, 4, 6, 3, 2, 2, 4, 6, 6, 6, 6, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4 } }, { 2826, 11, 12, 3, 9, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 8, 5, 11, 8, 4, 6, 6, 7, 7, 4, 7, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5, 6, 7, 6, 5, 11, 6, 7, 7, 7, 7, 7, 7, 8, 4, 5, 7, 6, 10, 8, 7, 6, 7, 7, 6, 6, 8, 7, 9, 7, 6, 6, 5, 5, 5, 7, 5, 4, 5, 5, 5, 5, 5, 4, 4, 5, 3, 3, 5, 3, 7, 5, 5, 5, 5, 4, 4, 4, 5, 4, 7, 4, 5, 4, 5, 3, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 7, 5, 3, 5, 5, 9, 5, 8, 7, 3, 9, 4, 4, 7, 3, 3, 4, 5, 8, 4, 3, 3, 5, 8, 7, 7, 7, 5, 6, 6, 6, 6, 6, 6, 9, 7, 7, 7, 7, 7, 4, 4, 4, 4, 7, 8, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 6, 6, 6, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 5, 5, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5 } }, { 2828, 12, 14, 3, 11, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 7, 7, 6, 12, 9, 4, 6, 6, 6, 7, 4, 8, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 9, 8, 9, 6, 12, 8, 8, 8, 9, 8, 8, 9, 10, 5, 6, 8, 8, 11, 9, 9, 8, 9, 8, 8, 7, 10, 8, 11, 8, 7, 7, 6, 5, 7, 8, 6, 5, 7, 6, 5, 6, 6, 3, 5, 6, 4, 4, 6, 4, 9, 6, 6, 6, 6, 5, 5, 3, 7, 6, 8, 6, 6, 6, 6, 4, 6, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 6, 6, 8, 6, 4, 7, 5, 11, 6, 9, 8, 4, 11, 4, 5, 7, 4, 4, 4, 7, 7, 3, 4, 4, 6, 9, 9, 9, 9, 6, 8, 8, 8, 8, 8, 8, 12, 8, 8, 8, 8, 8, 5, 5, 5, 5, 9, 9, 9, 9, 9, 9, 9, 7, 9, 10, 10, 10, 10, 7, 8, 7, 7, 7, 7, 7, 7, 7, 10, 5, 6, 6, 6, 6, 3, 3, 3, 3, 6, 7, 6, 6, 6, 6, 6, 7, 6, 7, 7, 7, 7, 6, 6, 6 } }, { 2830, 15, 15, 3, 12, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 8, 7, 14, 10, 5, 6, 6, 7, 9, 4, 9, 3, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 4, 8, 10, 8, 8, 15, 9, 9, 9, 10, 10, 9, 10, 11, 5, 7, 11, 9, 13, 11, 10, 9, 10, 10, 8, 10, 10, 10, 13, 9, 8, 8, 6, 6, 5, 8, 7, 5, 8, 7, 6, 7, 7, 5, 6, 8, 4, 4, 7, 4, 11, 8, 7, 7, 7, 6, 6, 4, 7, 6, 9, 6, 6, 6, 7, 4, 7, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 8, 7, 4, 8, 6, 12, 6, 8, 9, 5, 12, 6, 6, 9, 4, 4, 6, 7, 8, 4, 5, 4, 6, 8, 10, 10, 10, 8, 9, 9, 9, 9, 9, 9, 14, 9, 10, 10, 10, 10, 5, 5, 5, 5, 10, 11, 10, 10, 10, 10, 10, 9, 10, 10, 10, 10, 10, 8, 9, 7, 8, 8, 8, 8, 8, 8, 11, 6, 7, 7, 7, 7, 4, 4, 4, 4, 7, 8, 7, 7, 7, 7, 7, 9, 7, 7, 7, 7, 7, 6, 7, 6 } }, { 2834, 18, 19, 4, 15, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 9, 9, 9, 15, 15, 5, 6, 7, 10, 10, 5, 11, 5, 6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 7, 12, 11, 12, 9, 17, 13, 13, 13, 14, 12, 12, 14, 15, 7, 9, 12, 11, 17, 13, 14, 11, 14, 12, 11, 11, 14, 13, 17, 13, 11, 11, 7, 8, 6, 11, 9, 5, 10, 9, 8, 9, 9, 6, 8, 11, 5, 4, 9, 5, 14, 10, 10, 9, 9, 6, 7, 6, 10, 7, 11, 9, 7, 7, 6, 6, 7, 10, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 9, 9, 9, 10, 6, 9, 7, 15, 7, 10, 11, 6, 15, 6, 7, 10, 5, 5, 6, 10, 10, 5, 6, 5, 7, 11, 13, 13, 13, 9, 13, 13, 13, 13, 13, 13, 18, 13, 12, 12, 12, 12, 7, 7, 7, 7, 14, 13, 14, 14, 14, 14, 14, 10, 14, 14, 14, 14, 14, 11, 11, 10, 10, 10, 10, 10, 10, 10, 14, 8, 9, 9, 9, 9, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 9, 7 } }, { 2840, 23, 25, 5, 20, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 14, 15, 12, 20, 19, 8, 8, 8, 12, 14, 7, 15, 7, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 8, 8, 13, 13, 13, 12, 23, 16, 16, 16, 19, 16, 16, 18, 19, 10, 13, 17, 15, 22, 18, 18, 15, 18, 17, 14, 16, 18, 17, 21, 17, 14, 15, 10, 9, 10, 14, 13, 8, 13, 12, 10, 13, 10, 8, 11, 13, 7, 7, 13, 7, 19, 13, 12, 13, 12, 10, 10, 8, 13, 11, 16, 12, 11, 9, 7, 6, 10, 14, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 13, 13, 12, 13, 6, 12, 9, 19, 8, 13, 15, 8, 19, 8, 9, 14, 7, 7, 7, 13, 12, 7, 8, 7, 8, 13, 18, 18, 18, 12, 16, 16, 16, 16, 16, 16, 22, 16, 16, 16, 16, 16, 10, 10, 10, 10, 19, 18, 18, 18, 18, 18, 18, 13, 18, 18, 18, 18, 18, 14, 15, 13, 13, 13, 13, 13, 13, 13, 17, 11, 11, 11, 11, 11, 7, 7, 7, 7, 12, 13, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 14, 11, 13, 11 } }, { 3080, 9, 10, 2, 8, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 4, 5, 6, 6, 4, 3, 3, 4, 5, 2, 5, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 6, 5, 5, 4, 5, 6, 5, 6, 6, 5, 6, 5, 6, 2, 6, 6, 6, 8, 6, 6, 6, 6, 5, 5, 5, 6, 4, 7, 6, 7, 5, 2, 6, 2, 6, 4, 4, 6, 4, 5, 4, 4, 5, 5, 5, 3, 5, 5, 5, 5, 5, 4, 5, 4, 4, 5, 4, 5, 6, 6, 4, 6, 4, 4, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 5, 2, 6, 4, 6, 6, 6, 6, 8, 8, 5, 8, 5, 3, 5, 3, 5, 5, 6, 4, 4, 5, 5, 5, 5, 7, 5, 8, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 7, 5, 2, 6, 5, 5, 9, 8, 5, 8, 5, 6, 2, 6, 6, 7, 6, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 2, 2, 2, 6, 6, 6, 3, 3, 3, 3, 3, 3, 4, 4, 4, 2 } }, { 3082, 11, 10, 2, 8, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 5, 6, 8, 7, 5, 4, 4, 5, 6, 2, 6, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 7, 6, 6, 5, 6, 8, 6, 8, 7, 6, 8, 6, 8, 3, 7, 7, 7, 10, 8, 7, 8, 7, 6, 6, 6, 8, 5, 9, 7, 9, 6, 3, 7, 3, 7, 5, 5, 7, 5, 6, 5, 5, 6, 6, 6, 4, 6, 6, 6, 6, 6, 5, 6, 5, 5, 6, 5, 6, 8, 8, 5, 7, 5, 5, 2, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 6, 3, 7, 5, 7, 7, 7, 7, 10, 10, 6, 10, 6, 4, 6, 4, 6, 6, 7, 5, 5, 6, 6, 6, 6, 9, 6, 10, 7, 8, 7, 8, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 8, 10, 9, 6, 3, 7, 6, 6, 11, 10, 6, 10, 6, 7, 3, 8, 8, 9, 7, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 3, 3, 3, 7, 7, 7, 4, 4, 4, 4, 4, 4, 5, 5, 5, 3 } }, { 3084, 13, 14, 3, 11, { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 9, 7, 7, 10, 10, 6, 5, 5, 6, 7, 3, 7, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 7, 7, 7, 6, 7, 9, 8, 9, 8, 8, 10, 8, 9, 4, 8, 9, 9, 11, 9, 9, 9, 9, 7, 7, 8, 9, 7, 10, 8, 10, 8, 5, 9, 5, 8, 6, 6, 8, 7, 7, 7, 6, 8, 7, 8, 3, 8, 7, 7, 8, 7, 7, 7, 7, 7, 8, 6, 8, 9, 9, 6, 9, 6, 6, 3, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 3, 7, 4, 9, 6, 9, 7, 9, 9, 13, 12, 7, 12, 7, 5, 7, 5, 7, 7, 9, 6, 6, 7, 7, 7, 7, 11, 7, 13, 8, 10, 9, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 10, 9, 10, 10, 11, 10, 7, 3, 9, 8, 8, 13, 12, 8, 12, 8, 6, 4, 10, 10, 10, 9, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 3, 4, 4, 9, 9, 9, 5, 5, 5, 5, 5, 5, 6, 6, 6, 3 } }, { 3086, 15, 15, 3, 12, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 9, 7, 8, 12, 11, 6, 5, 5, 7, 8, 3, 8, 3, 4, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 8, 8, 8, 6, 8, 11, 9, 11, 9, 9, 11, 9, 11, 5, 9, 10, 10, 13, 11, 10, 11, 10, 8, 9, 9, 9, 7, 11, 9, 11, 9, 5, 10, 5, 10, 7, 7, 9, 8, 8, 7, 6, 9, 6, 8, 5, 9, 8, 8, 8, 8, 8, 8, 7, 8, 8, 6, 8, 11, 11, 7, 9, 7, 7, 3, 7, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 4, 8, 4, 10, 7, 11, 11, 11, 11, 15, 14, 9, 14, 9, 6, 8, 6, 8, 8, 10, 7, 7, 8, 8, 8, 8, 13, 9, 15, 10, 12, 10, 12, 12, 11, 11, 12, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 10, 12, 12, 11, 12, 8, 4, 10, 9, 9, 15, 14, 9, 14, 9, 7, 5, 12, 12, 11, 10, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 4, 5, 4, 10, 10, 10, 6, 6, 6, 6, 6, 6, 7, 7, 7, 4 } }, { 3090, 19, 20, 4, 16, { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 13, 9, 10, 15, 13, 8, 6, 6, 9, 10, 5, 9, 4, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 10, 10, 10, 8, 10, 14, 11, 14, 11, 11, 14, 11, 13, 6, 12, 14, 13, 16, 13, 13, 13, 13, 10, 11, 12, 13, 8, 14, 12, 15, 11, 6, 14, 6, 12, 9, 9, 12, 10, 10, 9, 8, 11, 8, 11, 6, 11, 10, 10, 11, 10, 10, 10, 10, 10, 11, 8, 11, 12, 12, 9, 13, 9, 9, 4, 9, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 12, 5, 10, 5, 13, 9, 14, 13, 13, 14, 19, 18, 10, 18, 10, 7, 10, 8, 10, 10, 12, 9, 9, 10, 10, 10, 10, 18, 10, 19, 12, 13, 13, 15, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 12, 12, 14, 13, 15, 15, 16, 15, 10, 4, 13, 11, 11, 18, 18, 11, 18, 11, 9, 6, 15, 15, 15, 13, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 5, 6, 6, 13, 13, 13, 7, 7, 7, 7, 7, 7, 9, 9, 9, 5 } }, { 3096, 26, 25, 5, 20, { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 17, 13, 13, 20, 17, 11, 8, 8, 12, 12, 6, 13, 6, 7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 6, 6, 13, 12, 13, 11, 13, 18, 15, 18, 15, 15, 19, 15, 18, 8, 16, 17, 17, 22, 18, 18, 18, 18, 14, 14, 16, 16, 11, 18, 16, 20, 15, 8, 18, 8, 16, 13, 13, 16, 12, 14, 12, 11, 14, 11, 15, 8, 14, 14, 14, 14, 13, 13, 14, 12, 12, 15, 11, 14, 18, 16, 12, 18, 12, 10, 4, 10, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 15, 6, 14, 4, 17, 13, 18, 18, 18, 18, 26, 25, 14, 25, 14, 9, 12, 10, 14, 13, 16, 12, 12, 12, 14, 13, 13, 24, 14, 25, 16, 14, 16, 19, 19, 18, 18, 20, 18, 18, 17, 17, 17, 17, 17, 16, 16, 19, 18, 18, 18, 22, 19, 14, 6, 17, 15, 15, 25, 25, 14, 25, 14, 12, 8, 18, 18, 20, 18, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12, 6, 8, 8, 17, 17, 17, 10, 10, 10, 10, 10, 10, 12, 12, 12, 6 } } }; /*********************************************************************** * * FUNCTION: * gr_init() * * INPUTS: * tp_width - (int) width of plotting area in pixels * tp_height - (int) height of plotting area in pixels * tp_mode - (int) mapping of screen to hardcopy * tp_title - (char *) title for output file * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * p_height - (static int) width of plotting area in pixels * p_width - (static int) height of plotting area in pixels * p_mode - (static int) mapping of screen to hardcopy * nfonts - (static int) number of fonts set to 0 * cur_font.fontnumber - (static int) 0xFFFF "unknown" * gr_state - (static enum) set to GR_OFF * title - (static char *) set to title * * DESCRIPTION: * Set parameters which define mapping of screen to hardcopy. * This is done to center hardcopy on a page. In additon, the * current font is set to "unknown", and the output device to * "off". */ void gr_init(int tp_width, int tp_height, int tp_mode, char *tp_title) { p_height = tp_height; p_width = tp_width; p_mode = tp_mode; title = (tp_title == NULL) ? "" : tp_title; nfonts = 0; cur_font.fontnumber = 0xFFFF; line_state = GR_SOLID_LINE; gr_state = GR_OFF; } /*********************************************************************** * * FUNCTION: * gr_init_colors() * * INPUTS: * p_background - (unsigned long) index of background color * p_foreground - (unsigned long) index of foreground color * p_highlight - (unsigned long) index of highlight color * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * background - (unsigned long) index of background color * foreground - (unsigned long) index of foreground color * highlight - (unsigned long) index of highlight color * * DESCRIPTION: * This routine sets the three colors used for the display. */ void gr_init_colors(unsigned long p_background, unsigned long p_foreground, unsigned long p_highlight) { foreground = p_foreground; background = p_background; highlight = p_highlight; } /*********************************************************************** * * FUNCTION: * gr_current_state() * * INPUTS: * * OUTPUTS: * * RETURNS: * the current state of gr_routines * GR_OFF * GR_SCREEN * GR_LASER * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * returns the current graphics state */ int gr_current_state(void) { return((int)gr_state); } /*********************************************************************** * * FUNCTION: * gr_screen_on() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Set up for screen mode. */ void gr_screen_on(GRDisplay *disp) { xdw = disp; cur_font.fontnumber = 0xFFFF; gr_state = GR_SCREEN; } /*********************************************************************** * * FUNCTION: * gr_screen_off() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Turn off screen mode. */ void gr_screen_off(void) { gr_state = GR_OFF; return; } /*********************************************************************** * * FUNCTION: * gr_laser_on() * * INPUTS: * ulp - (FILE *) pipe to laser printer process * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Initialize laser printer. */ void gr_laser_on(FILE *ulp, int flag) { float scale, xoff, yoff, yoff2; time_t now; /* current time */ now = time(NULL); lp = ulp; gr_state = GR_LASER; ps_state = PS_PATH_OFF; ps_path_len = 0; (void)fprintf(lp, "%%!PS-Adobe-1.0\n"); (void)fprintf(lp, "%%%%Title: %s\n", title); (void)fprintf(lp, "%%%%Creator: OEL GR Routines $Revision: 1.40 $\n"); (void)fprintf(lp, "%%%%CreationDate: %s", ctime(&now)); (void)fprintf(lp, "%%%%Pages: (atend)\n"); (void)fprintf(lp, "%%%%DocumentFonts: (atend)\n"); (void)fprintf(lp, "%%%%BoundingBox: 0 0 612 792\n"); (void)fprintf(lp, "%%%%EndComments\n"); (void)fprintf(lp, "/C { closepath } def\n"); (void)fprintf(lp, "/D { lineto } def\n"); (void)fprintf(lp, "/EX { exch } def\n"); (void)fprintf(lp, "/EO { eoclip } def\n"); (void)fprintf(lp, "/GS { gsave } def\n"); (void)fprintf(lp, "/GR { grestore } def\n"); (void)fprintf(lp, "/M { moveto } def\n"); (void)fprintf(lp, "/N { newpath } def\n"); (void)fprintf(lp, "/R { rotate } def\n"); (void)fprintf(lp, "/RL { rlineto } def\n"); (void)fprintf(lp, "/S { stroke } def\n"); (void)fprintf(lp, "/T { translate } def\n"); (void)fprintf(lp, "/PT { newpath moveto -0.25 0 rmoveto 0.5 0 rlineto\n"); (void)fprintf(lp, " stroke } def\n"); /* elliptical arcs and circles */ (void)fprintf(lp, "/ellipsedict 8 dict def\n"); (void)fprintf(lp, "ellipsedict /mtrx matrix put\n"); (void)fprintf(lp, "/ellipse {\n"); (void)fprintf(lp, " ellipsedict begin\n"); (void)fprintf(lp, " /endangle exch def\n"); (void)fprintf(lp, " /startangle exch def\n"); (void)fprintf(lp, " /yrad exch def\n"); (void)fprintf(lp, " /xrad exch def\n"); (void)fprintf(lp, " /yctr exch def\n"); (void)fprintf(lp, " /xctr exch def\n"); (void)fprintf(lp, " /savematrix mtrx currentmatrix def\n"); (void)fprintf(lp, " xctr yctr translate\n"); (void)fprintf(lp, " xrad yrad scale\n"); (void)fprintf(lp, " 0 0 1 startangle endangle arc\n"); (void)fprintf(lp, " savematrix setmatrix\n"); (void)fprintf(lp, " end\n"); (void)fprintf(lp, "} def\n"); (void)fprintf(lp, "/P0 { show } def\n"); (void)fprintf(lp, "/P1 { dup stringwidth pop 2 div neg 0 rmoveto show } def\n"); (void)fprintf(lp, "/P2 { dup stringwidth pop neg 0 rmoveto show } def\n"); fputs("/F { pagestate restore showpage } def\n", lp); /* * define scale: GR_EXPAND = 100 dpi, else 75 dpi */ if (p_mode & GR_EXPAND) { scale = 0.72; /* 100 pixels * 0.72 = 72 points = 1 inch */ } else { scale = 0.96; /* 75 pixels * 0.96 = 72 points = 1 inch */ } /* * set up so figure is centered */ if (p_mode & GR_LANDSCAPE) { xoff = ((11.0 * 72.0) / scale - p_width) / 2.0; yoff = - (p_height + (8.5 * 72.0) / scale) / 2.0; yoff2 = ((8.5 * 72.0) / scale - p_height) / 2.0; if (flag & GR_PDF) { fputs("systemdict /setdistillerparams known\n", lp); fputs("{\n", lp); (void)fprintf(lp, "/I { /pagestate save def %.3f %.3f" " scale %.3f %.3f translate\n .5 setlinewidth 0 setgray }" " def\n", scale, scale, xoff, yoff2); fputs("<> setpagedevice\n", lp); fputs("} {\n", lp); (void)fprintf(lp, "/I { /pagestate save def 90 rotate %.3f %.3f" " scale %.3f %.3f translate\n .5 setlinewidth 0 setgray }" " def\n", scale, scale, xoff, yoff); fputs("letter\n", lp); fputs("} ifelse\n", lp); } else { (void)fprintf(lp, "/I { /pagestate save def 90 rotate %.3f %.3f" " scale %.3f %.3f translate\n .5 setlinewidth 0 setgray }" " def\n", scale, scale, xoff, yoff); fputs("letter\n", lp); } } else { xoff = ((8.5 * 72.0) / scale - p_width) / 2.0; yoff = ((11.0 * 72.0) / scale - p_height) / 2.0; (void)fprintf(lp, "/I { /pagestate save def %.3f %.3f scale %.3f %.3f" " translate\n .5 setlinewidth 0 setgray } def\n", scale, scale, xoff, yoff); fputs("letter\n", lp); } (void)fprintf(lp, "%%%%EndProlog\n"); (void)fprintf(lp, "%%%%Page: ? %d\n", page_no = 1); (void)fprintf(lp, "I\n"); } /*********************************************************************** * * FUNCTION: * gr_laser_off() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Turn off laser printer. */ void gr_laser_off(void) { unsigned int i; gr_state = GR_OFF; if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); ps_state = PS_PATH_OFF; ps_path_len = 0; } fputs("F\n", lp); fputs("%%Trailer\n", lp); (void)fprintf(lp, "%%%%Pages: %d\n", page_no); fputs("%%DocumentFonts:", lp); for (i = 0; i < XtNumber(ps_fontnames); ++i) { if (ps_fonts & (1 << i)) { fputc(' ', lp); fputs(ps_fontnames[i], lp); } } fputc('\n', lp); } /*********************************************************************** * * FUNCTION: * gr_pict_on() * * INPUTS: * name - (char *) name of pict file * * OUTPUTS: * none * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Open a pict file and write the header. */ int gr_pict_on(char *name, int apple_single) { int status; status = pict_open(name, apple_single); gr_state = (status == 0) ? GR_PICT : GR_OFF; return status; } /*********************************************************************** * * FUNCTION: * gr_pict_off() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Turn off PICT mode. */ void gr_pict_off(void) { pict_close(); gr_state = GR_OFF; } /*********************************************************************** * * FUNCTION: * gr_wmf_on() * * INPUTS: * name - (char *) name of WMF file * * OUTPUTS: * none * * RETURNS: * 0 - (int) on success * -1 - (int) on failure * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * gr_state - (static enum) state of gr output * * DESCRIPTION: * Open a Windows Metafile and write the header plus a few * initialization commands. */ int gr_wmf_on(char *name) { int status; status = wmf_open(name); gr_state = (status == 0) ? GR_WMF : GR_OFF; return status; } /*********************************************************************** * * FUNCTION: * gr_wmf_off() * * INPUTS: * none * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * gr_state - (static enum) state of gr output * * DESCRIPTION: * Turn off WMF mode. */ void gr_wmf_off(void) { wmf_close(); gr_state = GR_OFF; } /*********************************************************************** * * FUNCTION: * gr_debug_on() * * INPUTS: * name - (char *) name of debug file * * OUTPUTS: * none * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Open a debug file and write the header. */ int gr_debug_on(char *name) { if ((debug_fp = fopen(name, "w")) == NULL) { return -1; } gr_state = GR_DEBUG; fprintf(debug_fp, "#include \n"); fprintf(debug_fp, "#include \n"); fprintf(debug_fp, "#include \n"); fprintf(debug_fp, "#include \"gr_plot.h\"\n\n"); fprintf(debug_fp, "void\ngrdbx_init()\n{\n"); fprintf(debug_fp, " gr_init(%d, %d, %d);\n", p_width, p_height, p_mode); fprintf(debug_fp, " gr_init_colors(%lu, %lu, %lu);\n", background, foreground, highlight); fprintf(debug_fp, "}\n\nvoid\ngrdbx_refresh()\n{\n"); return 0; } /*********************************************************************** * * FUNCTION: * gr_debug_off() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Turn off DEBUG mode. */ void gr_debug_off(void) { gr_state = GR_OFF; fprintf(debug_fp, "}\n"); fclose(debug_fp); debug_fp = NULL; } /*********************************************************************** * * FUNCTION: * gr_point * * INPUTS: * x - (int) horizontal location * y - (int) vertical location * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Draw a point at the specified location. */ void gr_point(int x, int y) { switch (gr_state) { case GR_SCREEN: xo = x; yo = y; XDrawPoint(xdw->display, xdw->win, xdw->gc, x, y); break; case GR_LASER: xo = x; yo = y; if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); } (void)fprintf(lp, "%.1f %.1f PT\n", scx(x), scy(y)); ps_state = PS_PATH_OFF; ps_path_len = 0; break; case GR_PICT: break; case GR_WMF: xo = x; yo = y; wmf_cmd(WMF_SETPIXEL); wmf_i16(0); wmf_i16(0); wmf_i16(y); wmf_i16(x); wmf_out(); break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_point(%d, %d);\n", x, y); break; } } /*********************************************************************** * * FUNCTION: * gr_move() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Move to point. */ void gr_move(int x, int y) { switch (gr_state) { case GR_SCREEN: xo = x; yo = y; break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); ps_state = PS_PATH_OFF; } ps_path_len = 0; xp = x; yp = y; xo = x; yo = y; break; case GR_PICT: xo = x; yo = y; break; case GR_WMF: wmf_cmd(WMF_MOVETO); wmf_i16(y); wmf_i16(x); wmf_out(); break; case GR_DEBUG: fprintf(debug_fp, " gr_move(%d, %d);\n", x, y); break; case GR_OFF: break; } } /*********************************************************************** * * FUNCTION: * gr_set_line() * * INPUTS: * line - (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * change line setting */ void gr_set_line(int line) { XGCValues gc_val; switch (gr_state) { case GR_SCREEN: switch (line) { case GR_SOLID_LINE: gc_val.line_style = LineSolid; break; case GR_DOT_LINE: gc_val.line_style = LineOnOffDash; XSetDashes(xdw->display, xdw->gc, 0, dotted, 2); break; case GR_SHORT_DASH: gc_val.line_style = LineOnOffDash; XSetDashes(xdw->display, xdw->gc, 0, short_dashed, 2); break; case GR_LONG_DASH: gc_val.line_style = LineOnOffDash; XSetDashes(xdw->display, xdw->gc, 0, long_dashed, 2); break; case GR_SHORT_DOT: gc_val.line_style = LineOnOffDash; XSetDashes(xdw->display, xdw->gc, 0, short_dot, 2); break; } XChangeGC(xdw->display, xdw->gc, GCLineStyle, &gc_val); line_state = line; break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); ps_state = PS_PATH_OFF; ps_path_len = 0; } switch (line) { case GR_SOLID_LINE: (void)fprintf(lp, "[] 0 setdash\n"); break; case GR_DOT_LINE: (void)fprintf(lp, "[1 3] 0 setdash\n"); break; case GR_SHORT_DASH: (void)fprintf(lp, "[4 4] 0 setdash\n"); break; case GR_LONG_DASH: (void)fprintf(lp, "[6 4] 0 setdash\n"); break; case GR_SHORT_DOT: (void)fprintf(lp, "[1 1] 0 setdash\n"); break; } line_state = line; break; case GR_PICT: pict_cmd(PICT_PNPAT); switch (line) { case GR_SOLID_LINE: pict_set(0xff, 8); break; case GR_DOT_LINE: pict_set(0xaa, 1); pict_set(0x55, 1); pict_set(0xaa, 1); pict_set(0x55, 1); pict_set(0xaa, 1); pict_set(0x55, 1); pict_set(0xaa, 1); pict_set(0x55, 1); break; case GR_SHORT_DASH: pict_set(0xcc, 2); pict_set(0x33, 2); pict_set(0xcc, 2); pict_set(0x33, 2); break; case GR_LONG_DASH: pict_set(0xf0, 4); pict_set(0x0f, 4); break; case GR_SHORT_DOT: pict_set(0xaa, 1); pict_set(0x55, 1); pict_set(0xaa, 1); pict_set(0x55, 1); pict_set(0xaa, 1); pict_set(0x55, 1); pict_set(0xaa, 1); pict_set(0x55, 1); break; } pict_out(); break; case GR_WMF: wmf_cmd(WMF_DELETEOBJECT); wmf_i16(0); wmf_out(); wmf_cmd(WMF_CREATEPENINDIRECT); switch (line) { case GR_SOLID_LINE: wmf_i16(0); break; case GR_DOT_LINE: wmf_i16(2); break; case GR_SHORT_DASH: wmf_i16(1); break; case GR_LONG_DASH: wmf_i16(1); break; case GR_SHORT_DOT: wmf_i16(2); break; } wmf_i16(1); wmf_i16(0); wmf_i16(0); wmf_i16(0); wmf_out(); wmf_cmd(WMF_SELECTOBJECT); wmf_i16(0); wmf_out(); break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_set_line(%d);\n", line); break; } } /*********************************************************************** * * FUNCTION: * gr_draw() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Draw to point. */ void gr_draw(int x, int y) { switch (gr_state) { case GR_SCREEN: XDrawLine(xdw->display, xdw->win, xdw->gc, xo, yo, x, y); xo = x; yo = y; break; case GR_LASER: if (ps_state == PS_PATH_OFF) { (void)fprintf(lp, "N %.1f %.1f M %.1f %.1f D\n", scx(xo), scy(yo), scx(x), scy(y)); ps_state = PS_PATH_ON; } else if ((x == xp) && (y == yp)) { (void)fprintf(lp, "%.1f %.1f D C S\n", scx(x), scy(y)); ps_state = PS_PATH_OFF; } else { (void)fprintf(lp, "%.1f %.1f D\n", scx(x), scy(y)); } ++ps_path_len; if (ps_path_len > MAX_PS_PATH_LEN) { (void)fprintf(lp, "S N %.1f %.1f M\n", scx(x), scy(y)); ps_path_len = 0; } xo = x; yo = y; break; case GR_PICT: pict_cmd(PICT_LINE); pict_i16(psc(yo)); pict_i16(psc(xo)); pict_i16(psc(y)); pict_i16(psc(x)); pict_out(); xo = x; yo = y; break; case GR_WMF: wmf_cmd(WMF_LINETO); wmf_i16(y); wmf_i16(x); wmf_out(); xo = x; yo = y; break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_draw(%d, %d);\n", x, y); break; } } /*********************************************************************** * * FUNCTION: * gr_line() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Draw a line between two points. */ void gr_line(int x1, int y1, int x2, int y2) { switch (gr_state) { case GR_SCREEN: XDrawLine(xdw->display, xdw->win, xdw->gc, x1, y1, x2, y2); xo = x2; yo = y2; break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); } (void)fprintf(lp, "N %.1f %.1f M %.1f %.1f D\n", scx(x1), scy(y1), scx(x2), scy(y2)); ps_state = PS_PATH_ON; ps_path_len = 1; xo = x2; yo = y2; break; case GR_PICT: pict_cmd(PICT_LINE); pict_i16(psc(y1)); pict_i16(psc(x1)); pict_i16(psc(y2)); pict_i16(psc(x2)); pict_out(); xo = x2; yo = y2; break; case GR_WMF: wmf_cmd(WMF_MOVETO); wmf_i16(y1); wmf_i16(x1); wmf_out(); wmf_cmd(WMF_LINETO); wmf_i16(y2); wmf_i16(x2); wmf_out(); xo = x2; yo = y2; break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_line(%d, %d, %d, %d);\n", x1, y1, x2, y2); break; } } /*********************************************************************** * * FUNCTION: * gr_masked_line() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * draw a usually non-solid line and overwrite background */ void gr_masked_line(int x1, int y1, int x2, int y2) { XGCValues gcval; int temp_state; /* Solid, Dashed, Dotted... */ XGetGCValues(xdw->display, xdw->gc, GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle, &gcval); switch (gr_state) { case GR_SCREEN: if (gcval.line_style != LineSolid) { XSetLineAttributes(xdw->display, xdw->gc, (unsigned int)gcval.line_width, LineDoubleDash, gcval.cap_style, gcval.join_style); } gr_line(x1, y1, x2, y2); XChangeGC(xdw->display, xdw->gc, GCLineStyle, &gcval); break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); ps_state = PS_PATH_OFF; } temp_state = line_state; gr_set_line(GR_SOLID_LINE); fprintf(lp, "N %.1f %.1f M %.1f %.1f D 1 setgray C S 0 setgray\n", scx(x1), scy(y1), scx(x2), scy(y2)); ps_state = PS_PATH_OFF; gr_set_line(temp_state); gr_line(x1, y1, x2, y2); break; case GR_PICT: pict_cmd(PICT_PNMODE); pict_i16(8); /* patCopy */ gr_line(x1, y1, x2, y2); pict_cmd(PICT_PNMODE); pict_i16(9); /* patOr */ pict_out(); break; case GR_WMF: break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_masked_line(%d, %d, %d, %d);\n", x1, y1, x2, y2); break; } } /*********************************************************************** * * FUNCTION: * gr_arc() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Plot an arc. */ void gr_arc(int x, int y, int dx, int dy, int ang1, int ang2) { float xctr, yctr; /* center of laser arc */ float xrad, yrad; /* radii of laser arc */ xrad = dx/2; yrad = dy/2; xctr = x + xrad; /* get arc center pts */ yctr = y + yrad; /* get arc center pts */ switch (gr_state) { case GR_SCREEN: XDrawArc(xdw->display, xdw->win, xdw->gc, x, y, (unsigned int)dx, (unsigned int)dy, ang1 * X_DEGREES, ang2 * X_DEGREES); xo = x + dx; yo = y + dy; break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); } if (dx != dy) { (void)fprintf(lp, "N %4.1f %4.1f %.1f %.1f %.1f %.1f ellipse S\n", scx(xctr), scy(yctr), xrad, yrad, (float)ang1, (float)(ang1 + ang2)); } else { (void)fprintf(lp, "N %4.1f %4.1f %.1f %.1f %.1f arc S\n", scx(xctr), scy(yctr), xrad, (float)ang1, (float)(ang1 + ang2) ); } ps_state = PS_PATH_OFF; ps_path_len = 0; xo = x + dx; yo = y + dy; break; case GR_PICT: case GR_WMF: case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_arc(%d, %d, %d, %d, %d, %d);\n", x, y, dx, dy, ang1, ang2); break; } } /*********************************************************************** * * FUNCTION: * gr_circle() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Draw a circle. */ void gr_circle(int x, int y, int r) { int xtmp, ytmp; unsigned int width, height; xtmp = x - r; /* get the upper left coordinates, the */ ytmp = y - r; /* width, and the height of the rectangle */ width = 2 * r; /* which contains the circle */ height = 2 * r; switch(gr_state) { case GR_SCREEN: /* * draw a circle inside a square. start arc at 0 degrees and * continue for 360 * 64 degrees */ XDrawArc(xdw->display, xdw->win, xdw->gc, xtmp, ytmp, width, height, 0, FULL_CIRCLE * X_DEGREES); break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); } (void)fprintf(lp, "N %.1f %.1f %d 0 360 arc S\n", scx(x), scy(y), r); ps_state = PS_PATH_OFF; ps_path_len = 0; break; case GR_PICT: pict_cmd(PICT_FRAMEOVAL); pict_i16(psc(y - r)); pict_i16(psc(x - r)); pict_i16(psc(y + r)); pict_i16(psc(x + r)); pict_out(); break; case GR_WMF: break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_circle(%d, %d, %d);\n", x, y, r); break; } } /*********************************************************************** * * FUNCTION: * gr_circle_fill() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Draw a circle. */ void gr_circle_fill(int x, int y, int r) { int xtmp, ytmp; unsigned int width, height; xtmp = x - r; /* get the upper left coordinates, the */ ytmp = y - r; /* width, and the height of the rectangle */ width = 2 * r; /* which contains the circle */ height = 2 * r; switch(gr_state) { case GR_SCREEN: /* * draw a circle inside a square. start arc at 0 degrees and * continue for 360 * 64 degrees */ XFillArc(xdw->display, xdw->win, xdw->gc, xtmp, ytmp, width, height, 0, FULL_CIRCLE * X_DEGREES); break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); } (void)fprintf(lp, "N %.1f %.1f %d 0 360 arc fill\n", scx(x), scy(y), r); ps_state = PS_PATH_OFF; ps_path_len = 0; break; case GR_PICT: pict_cmd(PICT_FRAMEOVAL); pict_i16(psc(y - r)); pict_i16(psc(x - r)); pict_i16(psc(y + r)); pict_i16(psc(x + r)); pict_out(); break; case GR_WMF: break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_circle(%d, %d, %d);\n", x, y, r); break; } } /*********************************************************************** * * FUNCTION: * gr_poly() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Plots out a polygon. */ void gr_poly(XPoint *points, int npoints) { int i; int xmin, ymin, xmax, ymax; switch(gr_state) { case GR_SCREEN: XDrawLines(xdw->display, xdw->win, xdw->gc, points, npoints, CoordModeOrigin); /* * if the first and last points are not * the same, then draw a line from the * first point to the last point */ if ((points[0].x != points[npoints-1].x) || (points[0].y != points[npoints-1].y)) { XDrawLine(xdw->display, xdw->win, xdw->gc, points[0].x, points[0].y, points[npoints-1].x, points[npoints-1].y); } break; case GR_LASER: if (ps_state==PS_PATH_ON) { (void)fprintf(lp, "S\n"); } i = 0; (void)fprintf(lp,"N %.1f %.1f M\n",scx(points[i].x), scy(points[i].y)); for(i = 1; i < npoints; i++) { (void)fprintf(lp, " %4.1f %4.1f D\n", scx(points[i].x), scy(points[i].y)); } /* * if the first and last points are not * the same, then draw a line from the * first point to the last point */ if ( (points[0].x != points[npoints-1].x) || (points[0].y != points[npoints-1].y)) { (void)fprintf(lp, " %4.1f %4.1f D\n", scx(points[0].x), scy(points[0].y)); } (void)fprintf(lp,"C S\n"); ps_state = PS_PATH_OFF; ps_path_len = 0; break; case GR_PICT: xmin = xmax = points[0].x; ymin = ymax = points[0].y; for (i = 1; i < npoints; ++i) { if (points[i].x < xmin) xmin = points[i].x; if (points[i].x > xmax) xmax = points[i].x; if (points[i].y < ymin) ymin = points[i].y; if (points[i].y > ymax) ymax = points[i].y; } pict_cmd(PICT_FRAMEPOLY); pict_i16(10 + 4 * (npoints + 1)); /* nbytes */ pict_i16(psc(ymin)); /* rectangle */ pict_i16(psc(xmin)); pict_i16(psc(ymax)); pict_i16(psc(xmax)); for (i = 0; i < npoints; ++i) { /* points */ pict_i16(psc(points[i].y)); pict_i16(psc(points[i].x)); } pict_i16(psc(points[0].y)); pict_i16(psc(points[0].x)); pict_out(); break; case GR_WMF: wmf_cmd(WMF_POLYLINE); wmf_i16(npoints + 1); for (i = 0; i < npoints; ++i) { wmf_i16(points[i].x); wmf_i16(points[i].y); } wmf_i16(points[0].x); wmf_i16(points[0].y); wmf_out(); break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " {\n\tXPoint p[] = {\n"); for(i = 0; i < npoints - 1; i++) { fprintf(debug_fp, "\t { %d, %d },\n", points[i].x, points[i].y); } fprintf(debug_fp, "\t { %d, %d }\n", points[i].x, points[i].y); fprintf(debug_fp, "\t};\n\n\tgr_poly(p, %d);\n }\n", npoints); break; } } /*********************************************************************** * * FUNCTION: * gr_rectangle() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Draw a rect, coords in pixels. */ void gr_rectangle(int x, int y, int dx, int dy) { switch (gr_state) { case GR_SCREEN: XDrawRectangle(xdw->display, xdw->win, xdw->gc, x, y, (unsigned int)dx, (unsigned int)dy); break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf (lp, "S\n"); ps_state = PS_PATH_OFF; } (void)fprintf(lp, "N %4.1f %4.1f M\n", scx(x), scy(y)); (void)fprintf(lp, " %4.1f %4.1f D\n", scx(x + dx), scy(y)); (void)fprintf(lp, " %4.1f %4.1f D\n", scx(x + dx), scy(y + dy)); (void)fprintf(lp, " %4.1f %4.1f D C S\n", scx(x), scy(y + dy)); ps_state = PS_PATH_OFF; ps_path_len = 0; break; case GR_PICT: pict_cmd(PICT_FRAMERECT); pict_i16(psc(y)); pict_i16(psc(x)); pict_i16(psc(y + dy)); pict_i16(psc(x + dx)); pict_out(); break; case GR_WMF: wmf_cmd(WMF_POLYLINE); wmf_i16(5); wmf_i16(x); wmf_i16(y); wmf_i16(x + dx); wmf_i16(y); wmf_i16(x + dx); wmf_i16(y + dy); wmf_i16(x); wmf_i16(y + dy); wmf_i16(x); wmf_i16(y); wmf_out(); break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_rectangle(%d, %d, %d, %d);\n", x, y, dx, dy); break; } } /*********************************************************************** * * FUNCTION: * gr_clear() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * In screen mode, clear the screen. */ void gr_clear(void) { switch(gr_state) { case GR_SCREEN: XClearWindow(xdw->display, xdw->win); break; case GR_LASER: break; case GR_PICT: case GR_WMF: case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_clear();\n"); break; } } /*********************************************************************** * * FUNCTION: * gr_page() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * In printer mode, output a page. */ void gr_page(void) { switch(gr_state) { case GR_SCREEN: XClearWindow(xdw->display, xdw->win); break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); ps_state = PS_PATH_OFF; ps_path_len = 0; } (void)fprintf(lp, "F\n"); (void)fprintf(lp, "%%%%Page: ? %d\n", ++page_no); (void)fprintf(lp, "I\n"); break; case GR_PICT: case GR_WMF: case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_page();\n"); break; } } /*********************************************************************** * * FUNCTION: * gr_poly_clear() * * INPUTS: * points - (XPoint *) * npoints - (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Clear (set to background color) the specified polygon. * */ void gr_poly_clear(XPoint *points, int npoints) { int i; int xmin, ymin, xmax, ymax; XGCValues gc_val; switch(gr_state) { case GR_SCREEN: XGetGCValues(xdw->display, xdw->gc, GCForeground|GCBackground, &gc_val); XSetForeground(xdw->display, xdw->gc, gc_val.background); XFillPolygon(xdw->display, xdw->win, xdw->gc, points, npoints, Complex, CoordModeOrigin); XSetForeground(xdw->display, xdw->gc, gc_val.foreground); break; case GR_LASER: if (ps_state==PS_PATH_ON) { (void)fprintf(lp, "S\n"); } i = 0; (void)fprintf(lp,"N %.1f %.1f M\n",scx(points[i].x), scy(points[i].y)); for(i = 1; i < npoints; i++) { (void)fprintf(lp, " %4.1f %4.1f D\n", scx(points[i].x), scy(points[i].y)); } (void)fprintf(lp, "1 setgray fill 0 setgray\n"); break; case GR_PICT: xmin = xmax = points[0].x; ymin = ymax = points[0].y; for (i = 1; i < npoints; ++i) { if (points[i].x < xmin) xmin = points[i].x; if (points[i].x > xmax) xmax = points[i].x; if (points[i].y < ymin) ymin = points[i].y; if (points[i].y > ymax) ymax = points[i].y; } pict_cmd(PICT_ERASEPOLY); pict_i16(10 + 4 * npoints); /* nbytes */ pict_i16(psc(ymin)); /* rectangle */ pict_i16(psc(xmin)); pict_i16(psc(ymax)); pict_i16(psc(xmax)); for (i = 0; i < npoints; ++i) { /* points */ pict_i16(psc(points[i].y)); pict_i16(psc(points[i].x)); } pict_out(); break; case GR_WMF: break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " {\n\tXPoint p[] = {\n"); for(i = 0; i < npoints - 1; i++) { fprintf(debug_fp, "\t { %d, %d },\n", points[i].x, points[i].y); } fprintf(debug_fp, "\t { %d, %d }\n", points[i].x, points[i].y); fprintf(debug_fp, "\t};\n\n\tgr_poly_clear(p, %d);\n }\n", npoints); break; } } /*********************************************************************** * * FUNCTION: * gr_rect_clear() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Clear (set to background color) the specified rectangle. */ void gr_rect_clear(int x, int y, int dx, int dy) { switch (gr_state) { case GR_SCREEN: XSetForeground(xdw->display, xdw->gc, background); XFillRectangle(xdw->display, xdw->win, xdw->gc, x, y, (unsigned int)dx, (unsigned int)dy); XSetForeground(xdw->display, xdw->gc, foreground); break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf (lp, "S\n"); ps_state = PS_PATH_OFF; } (void)fprintf(lp, "N %.1f %.1f M\n", scx(x - 1), scy(y - 1)); (void)fprintf(lp, " %.1f %.1f D\n", scx(x + dx), scy(y - 1)); (void)fprintf(lp, " %.1f %.1f D\n", scx(x + dx), scy(y + dy)); (void)fprintf(lp, " %.1f %.1f D C\n", scx(x - 1), scy(y + dy)); (void)fprintf(lp, "1 setgray fill 0 setgray\n"); break; case GR_PICT: pict_cmd(PICT_ERASERECT); pict_i16(psc(y)); pict_i16(psc(x)); pict_i16(psc(y + dy)); pict_i16(psc(x + dx)); pict_out(); break; case GR_WMF: break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_rect_clear(%d, %d, %d, %d);\n", x, y, dx, dy); break; } } /*********************************************************************** * * FUNCTION: * gr_poly_fill() * * INPUTS: * points - (XPoint *) * npoints - (int) * fcolor - (char *) * gs - (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * */ void gr_poly_fill(XPoint *points, int npoints, char *fcolor, int gs) { int i; int xmin, ymin, xmax, ymax; XGCValues gc_val; switch(gr_state) { case GR_SCREEN: if (strcmp(fcolor, "") != 0) { XGetGCValues(xdw->display, xdw->gc, GCForeground, &gc_val); XSetForeground(xdw->display, xdw->gc, find_color_black(fcolor)); } XDrawLines(xdw->display, xdw->win, xdw->gc, points, npoints, CoordModeOrigin); XFillPolygon(xdw->display, xdw->win, xdw->gc, points, npoints, Complex, CoordModeOrigin); if (strcmp(fcolor, "") != 0) { XSetForeground(xdw->display, xdw->gc, gc_val.foreground); } break; case GR_LASER: if (ps_state==PS_PATH_ON) { (void)fprintf(lp, "S\n"); } i = 0; (void)fprintf(lp,"N %.1f %.1f M\n",scx(points[i].x), scy(points[i].y)); for(i = 1; i < npoints; i++) { (void)fprintf(lp, " %4.1f %4.1f D\n", scx(points[i].x), scy(points[i].y)); } (void)fprintf(lp, "%.2f setgray fill 0 setgray\n", 1.0 - (gs * 0.01)); break; case GR_PICT: xmin = xmax = points[0].x; ymin = ymax = points[0].y; for (i = 1; i < npoints; ++i) { if (points[i].x < xmin) xmin = points[i].x; if (points[i].x > xmax) xmax = points[i].x; if (points[i].y < ymin) ymin = points[i].y; if (points[i].y > ymax) ymax = points[i].y; } pict_cmd(PICT_FILLPOLY); pict_i16(10 + 4 * npoints); /* nbytes */ pict_i16(psc(ymin)); /* rectangle */ pict_i16(psc(xmin)); pict_i16(psc(ymax)); pict_i16(psc(xmax)); for (i = 0; i < npoints; ++i) { /* points */ pict_i16(psc(points[i].y)); pict_i16(psc(points[i].x)); } pict_out(); break; case GR_WMF: wmf_cmd(WMF_POLYGON); wmf_i16(npoints); for (i = 0; i < npoints; ++i) { wmf_i16(points[i].x); wmf_i16(points[i].y); } wmf_out(); break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " {\n\tXPoint p[] = {\n"); for(i = 0; i < npoints - 1; i++) { fprintf(debug_fp, "\t { %d, %d },\n", points[i].x, points[i].y); } fprintf(debug_fp, "\t { %d, %d }\n", points[i].x, points[i].y); fprintf(debug_fp, "\t};\n\n"); fprintf(debug_fp, "\tgr_poly_fill(p, %d, \"%s\", %d);\n }\n", npoints, fcolor, gs); break; } } /*********************************************************************** * * FUNCTION: * gr_rect_fill() * * INPUTS: * x - (int) * y - (int) * dx - (int) * dy - (int) * fcolor - (char *) * gs - (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * fill a rectangle * */ void gr_rect_fill(int x, int y, int dx, int dy, char *fcolor, int gs) { XGCValues gc_val; switch (gr_state) { case GR_SCREEN: if (strcmp(fcolor, "") != 0) { XGetGCValues(xdw->display, xdw->gc, GCForeground, &gc_val); XSetForeground(xdw->display, xdw->gc, find_color_black(fcolor)); } XDrawRectangle(xdw->display, xdw->win, xdw->gc, x, y, (unsigned int)dx, (unsigned int)dy); XFillRectangle(xdw->display, xdw->win, xdw->gc, x, y, (unsigned int)dx, (unsigned int)dy); if (strcmp(fcolor, "") != 0) { XSetForeground(xdw->display, xdw->gc, gc_val.foreground); } break; case GR_LASER: if (ps_state == PS_PATH_ON) { fprintf (lp, "S\n"); ps_state = PS_PATH_OFF; } (void)fprintf(lp, "N %.1f %.1f M\n", scx(x), scy(y)); (void)fprintf(lp, "%.1f %.1f D\n", scx(x + dx), scy(y)); (void)fprintf(lp, "%.1f %.1f D\n", scx(x + dx), scy(y + dy)); (void)fprintf(lp, "%.1f %.1f D C\n", scx(x), scy(y + dy)); (void)fprintf(lp, "%.2f setgray fill 0 setgray\n", 1.0 - (gs * 0.01)); break; case GR_PICT: pict_cmd(PICT_FILLRECT); pict_i16(psc(y)); pict_i16(psc(x)); pict_i16(psc(y + dy)); pict_i16(psc(x + dx)); pict_out(); break; case GR_WMF: wmf_cmd(WMF_POLYGON); wmf_i16(5); wmf_i16(x); wmf_i16(y); wmf_i16(x + dx); wmf_i16(y); wmf_i16(x + dx); wmf_i16(y + dy); wmf_i16(x); wmf_i16(y + dy); wmf_i16(x); wmf_i16(y); wmf_out(); break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_rect_fill(%d, %d, %d, %d, \"%s\", %d);\n", x, y, dx, dy, fcolor, gs); break; } } /*********************************************************************** * * FUNCTION: * gr_rect_shade() * * INPUTS: * x - (int) * y - (int) * dx - (int) * dy - (int) * gs - (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * shades a rectangle to the printer and not to the screen. * */ void gr_rect_shade(int x, int y, int dx, int dy, int gc) { switch (gr_state) { case GR_SCREEN: XDrawRectangle(xdw->display, xdw->win, xdw->gc, x, y, (unsigned int)dx, (unsigned int)dy); break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf (lp, "S\n"); ps_state = PS_PATH_OFF; } (void)fprintf(lp, "N %4.1f %4.1f M\n", scx(x - 1), scy(y - 1)); (void)fprintf(lp, " %4.1f %4.1f D\n", scx(x - 1 + dx), scy(y - 1)); (void)fprintf(lp, " %4.1f %4.1f D\n", scx(x - 1 + dx), scy(y - 1 + dy)); (void)fprintf(lp, " %4.1f %4.1f D C\n", scx(x - 1), scy(y - 1 + dy)); (void)fprintf(lp, "%.2f setgray fill 0 setgray\n", 1.0 - (gc * 0.01)); ps_state = PS_PATH_ON; break; case GR_PICT: case GR_WMF: case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_rect_shade(%d, %d, %d, %d, %d);\n", x, y, dx, dy, gc); break; } } /*********************************************************************** * * FUNCTION: * gr_hilight() * * INPUTS: * x, y - (int) upper left corner of highlight * height, width - (int) width and height of highlight * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This routine sets a highlight for a specified rectangle. */ void gr_hilight(int x, int y, int width, int height) { switch (gr_state) { case GR_SCREEN: XSetForeground(xdw->display, xdw->gc, highlight); XFillRectangle(xdw->display, xdw->win, xdw->gc, x, y, (unsigned int)width, (unsigned int)height); XSetForeground(xdw->display, xdw->gc, foreground); break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf (lp, "S\n"); ps_state = PS_PATH_OFF; } (void)fprintf(lp, "N %4.1f %4.1f M\n", scx(x - 1), scy(y - 1)); (void)fprintf(lp, " %4.1f %4.1f D\n", scx(x - 1 + width), scy(y - 1)); (void)fprintf(lp, " %4.1f %4.1f D\n", scx(x - 1 + width), scy(y - 1 + height)); (void)fprintf(lp, " %4.1f %4.1f D C\n", scx(x - 1), scy(y - 1 + height)); (void)fprintf(lp, "%.2f setgray fill 0 setgray\n", .85); ps_state = PS_PATH_ON; break; case GR_PICT: case GR_WMF: case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_hilight(%d, %d, %d, %d);\n", x, y, width, height); break; } } /*********************************************************************** * * FUNCTION: * open_xfont() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Open a font. */ static void open_xfont(char *fontname, int fontindex) { if ((x_fonts[nfonts].font_struct = XLoadQueryFont(xdw->display, fontname)) == NULL) { (void)printf("Font %s not found\n", fontname); return; } XSetFont(xdw->display, xdw->gc, x_fonts[nfonts].font_struct->fid); x_fonts[nfonts].fontnumber = fontindex; cur_font = x_fonts[nfonts]; nfonts++; } /*********************************************************************** * * FUNCTION: * screen_font() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Set screen font, if necessary open new fonts. */ static void screen_font(int font) { char *name; /* font name for laser and screen */ char fontname[64]; /* complete font name */ int i; /* index */ if (cur_font.fontnumber == font) return; cur_font.fontnumber = 0xFFFF; if ((xdw == NULL) || (xdw->display == NULL)) { cur_font.index = 2; for (i = 0; XtNumber(font_metrics); i++) { if (font == font_metrics[i].font) { x_fonts[i].index = i; cur_font = x_fonts[i]; return; } } } else { for (i = 0; i < nfonts; i++) { if (font == x_fonts[i].fontnumber) { XSetFont(xdw->display, xdw->gc, x_fonts[i].font_struct->fid); cur_font = x_fonts[i]; return; } } switch(font & NAMEMASK) { case GR_COURIER: name = "courier-medium-r"; break; case GR_COURIER_BOLD: name = "courier-bold-r"; break; case GR_COURIER_ITALIC: name = "courier-medium-o"; break; case GR_COURIER_BOLD_ITALIC: name = "courier-bold-o"; break; case GR_HELVETICA: name = "helvetica-medium-r"; break; case GR_HELVETICA_BOLD: name = "helvetica-bold-r"; break; case GR_HELVETICA_ITALIC: name = "helvetica-medium-o"; break; case GR_HELVETICA_BOLD_ITALIC: name = "helvetica-bold-o"; break; case GR_TIMES: name = "times-medium-r"; break; case GR_TIMES_BOLD: name = "times-bold-r"; break; case GR_TIMES_ITALIC: name = "times-medium-i"; break; case GR_TIMES_BOLD_ITALIC: name = "times-bold-i"; break; case GR_SYMBOL: name = "symbol-medium-r"; break; default: name = "courier-medium-r"; break; } (void)sprintf(fontname, "*-%s-*--%d-*", name, font & POINTMASK); open_xfont(fontname, font); /* open it and set it */ } } /*********************************************************************** * * FUNCTION: * set_font() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Local function to set font for both screen and laser. */ static void set_font(int font) { int point; /* point size for font */ int fname; /* font integer name */ char *name; /* font name for laser and screen */ int face; /* PICT typeface */ switch(gr_state) { case GR_SCREEN: screen_font(font); break; case GR_LASER: point = font & POINTMASK; fname = font & NAMEMASK; switch(fname) { case GR_COURIER: case GR_COURIER_BOLD: case GR_COURIER_ITALIC: case GR_COURIER_BOLD_ITALIC: case GR_HELVETICA: case GR_HELVETICA_BOLD: case GR_HELVETICA_ITALIC: case GR_HELVETICA_BOLD_ITALIC: case GR_TIMES: case GR_TIMES_BOLD: case GR_TIMES_ITALIC: case GR_TIMES_BOLD_ITALIC: case GR_SYMBOL: name = ps_fontnames[fname >> 8]; /* * "or" specified font into list of fonts required */ ps_fonts |= 1 << (fname >> 8); break; default: name = ps_fontnames[GR_COURIER >> 8]; ps_fonts |= 1 << (GR_COURIER >> 8); break; } (void)fprintf(lp, "/%s findfont\n %d scalefont \n setfont\n", name, point); break; case GR_PICT: if (font != pict_font) { pict_font = font; point = font & POINTMASK; fname = font & NAMEMASK; switch(fname) { case GR_COURIER: fname = 22; face = 0; break; case GR_COURIER_BOLD: fname = 22; face = 1; break; case GR_COURIER_ITALIC: fname = 22; face = 2; break; case GR_COURIER_BOLD_ITALIC: fname = 22; face = 3; break; case GR_HELVETICA: fname = 21; face = 0; break; case GR_HELVETICA_BOLD: fname = 21; face = 1; break; case GR_HELVETICA_ITALIC: fname = 21; face = 2; break; case GR_HELVETICA_BOLD_ITALIC: fname = 21; face = 3; break; case GR_TIMES: fname = 20; face = 0; break; case GR_TIMES_BOLD: fname = 20; face = 1; break; case GR_TIMES_ITALIC: fname = 20; face = 2; break; case GR_TIMES_BOLD_ITALIC: fname = 20; face = 3; break; case GR_SYMBOL: fname = 23; face = 0; break; default: fname = 22; face = 0; break; } pict_cmd(PICT_TXFONT); pict_i16(fname); pict_cmd(PICT_TXFACE); pict_set(face, 1); pict_cmd(PICT_TXSIZE); pict_i16(psc(point)); pict_out(); } break; case GR_WMF: if (font != wmf_font) { wmf_cmd(WMF_DELETEOBJECT); wmf_i16(1); wmf_out(); wmf_cmd(WMF_CREATEFONTINDIRECT); wmf_i16(-(font & GR_FONT_SIZE)); wmf_i16(0); wmf_i16(0); wmf_i16(0); wmf_i16((font & GR_BOLD) ? 700 : 400); wmf_i16((font & GR_ITALIC) ? 1 : 0); wmf_i16(0); wmf_i16(0); switch (font & GR_FONT_FAMILY) { case GR_COURIER: wmf_i16(0x3000); wmf_str("Courier New", (int)strlen("Courier New") + 1); break; case GR_HELVETICA: wmf_i16(0x2000); wmf_str("Arial", (int)strlen("Arial") + 1); break; case GR_TIMES: wmf_i16(0x1000); wmf_str("Times New Roman", (int)strlen("Times New Roman") + 1); break; case GR_SYMBOL: wmf_i16(0x5000); wmf_str("Symbol", (int)strlen("Symbol") + 1); break; } wmf_out(); wmf_cmd(WMF_SELECTOBJECT); wmf_i16(1); wmf_out(); wmf_font = font; } break; case GR_OFF: case GR_DEBUG: break; } } /*********************************************************************** * * FUNCTION: * char_mid() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Find pixel midpoint of a string. */ static int char_mid(char *character) { int mid; if (cur_font.font_struct->per_char == NULL) { mid = 0; } else { mid = (cur_font.font_struct->per_char[character[0]].lbearing + (cur_font.font_struct->max_bounds.width - cur_font.font_struct->per_char[character[0]].rbearing)) / 2; } return(mid); } /*********************************************************************** * * FUNCTION: * gr_free_fonts() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Free all fonts that have been loaded. */ void gr_free_fonts(void) { int i; for (i = 0; i < nfonts; i++) { XFreeFont(xdw->display, x_fonts[i].font_struct); } } /*********************************************************************** * * FUNCTION: * gr_text() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Draw text at specified point. */ void gr_text(int x, int y, char *str, int just, int font, int mask) { int xs; /* shift of origin */ int ydes; /* y descent */ int dx, dy; /* text width, text height */ int sx, sy; /* start x & start y for laser */ int i, j; /* text indices */ int length; /* character length of text */ char buf[256]; xs = 0; set_font(font); length = strlen(str); dx = gr_strwidth(str, font); dy = gr_txheight(font); ydes = gr_txdescent(font); switch (just) { case GR_LEFT: xs = 0; break; case GR_CENTER: xs = dx / 2; break; case GR_RIGHT: xs = dx; break; } switch (gr_state) { case GR_SCREEN: if (mask) { /* white out the background rectangle */ XDrawImageString(xdw->display, xdw->win, xdw->gc, x - xs, y - ydes, str, length); } else { XDrawString(xdw->display, xdw->win, xdw->gc, x - xs, y - ydes, str, length); } break; case GR_LASER: if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); ps_state = PS_PATH_OFF; } i = 0; j = 0; while (str[i]) { switch (str[i]) { case ')': case '(': case '\\': buf[j++] = '\\'; default: buf[j++] = str[i++]; } } buf[j] = '\0'; sx = x - xs; sy = y - dy; if (mask) { (void)fprintf(lp, "N %.1f %.1f M\n", scx(sx), scy(sy)); (void)fprintf(lp, " %.1f %.1f D\n", scx(sx + dx), scy(sy)); (void)fprintf(lp, " %.1f %.1f D\n", scx(sx + dx), scy(sy + dy)); (void)fprintf(lp, " %.1f %.1f D C\n", scx(sx), scy(sy + dy)); (void)fprintf(lp, "1 setgray fill 0 setgray\n"); } (void)fprintf(lp, "%.1f %.1f M (%s) P%d\n", scx(x), scy(y-ydes), buf, just); break; case GR_PICT: pict_cmd(PICT_LONGTEXT); pict_i16(psc(y - ydes)); pict_i16(psc(x - xs)); pict_set(length, 1); pict_str(str, length); pict_out(); break; case GR_WMF: set_font(font); length = strlen(str); wmf_cmd(WMF_TEXTOUT); wmf_i16(length); wmf_str(str, length); wmf_i16(y - dy); wmf_i16(x - xs); wmf_out(); break; case GR_OFF: break; case GR_DEBUG: fprintf(debug_fp, " gr_text(%d, %d, \"%s\", %d, %d, %d);\n", x, y, str, just, font, mask); break; } } /*********************************************************************** * * FUNCTION: * gr_rotate_text() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Draw rotated text at specified point. */ void gr_rotate_text(int x, int y, char *str, int font, int rotate) { int ydes; /* y descent */ int i, j; /* text indices */ char buff[64]; int length; /* character length of text */ unsigned int tex_length; /* width in pixels of text */ unsigned int tex_height; /* height in pixels of text */ Pixmap pixtemp1; /* temporary pixmap image of text */ Pixmap pixtemp2; /* temporary rotated pixmap of image */ static GC newgc; /* New context for rotated image */ XImage *xi1; /* temporary image of text */ XImage *xi2; /* rotated image of text */ unsigned long pixval; /* pixel value */ static unsigned long gcmask;/* valuemask for newgc */ int old_x, old_y; /* image position */ int xrotate, yrotate; /* rotated image position */ if (! *str) { /* null string */ return; } set_font(font); length = strlen(str); ydes = gr_txdescent(font); tex_length = gr_strwidth(str, font); tex_height = gr_txheight(font); switch (gr_state) { case GR_SCREEN: pixtemp1 = XCreatePixmap(xdw->display, xdw->win, tex_length, tex_height, (unsigned int)DefaultDepth(xdw->display, xdw->screen)); pixtemp2 = XCreatePixmap(xdw->display, xdw->win, tex_height, tex_length, (unsigned int)DefaultDepth(xdw->display, xdw->screen)); if (!newgc) { gcmask = GCFunction | GCPlaneMask | GCForeground | GCBackground | GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle | GCFillRule | GCTile | GCStipple | GCFont | GCTileStipXOrigin | GCTileStipYOrigin | GCSubwindowMode | GCGraphicsExposures | GCDashOffset | GCDashList | GCArcMode; newgc = XCreateGC(xdw->display, pixtemp2, 0, NULL); } /* draw and transfer to image */ XCopyGC(xdw->display, xdw->gc, gcmask, newgc); XDrawImageString(xdw->display, pixtemp1, newgc, 0, (int)tex_height - ydes, str, length); xi1 = XGetImage(xdw->display, pixtemp1, 0, 0, tex_length, tex_height, AllPlanes, ZPixmap); xi2 = XGetImage(xdw->display, pixtemp2, 0, 0, tex_height, tex_length, AllPlanes, ZPixmap); for (old_x = 0; old_x < (int)tex_length; old_x++) { for (old_y = 0; old_y < (int)tex_height; old_y++) { switch (rotate) { case GR_DEGREE90: xrotate = old_y; yrotate = tex_length - old_x - 1; break; case GR_DEGREE270: xrotate = tex_height - old_y - 1; yrotate = old_x; break; } pixval = XGetPixel(xi1, old_x, old_y); XPutPixel(xi2, xrotate, yrotate, pixval); } } switch (rotate) { case GR_DEGREE90: XPutImage(xdw->display, pixtemp2, newgc, xi2, 0, 0, 0, 0, tex_height, tex_length); XCopyArea(xdw->display, pixtemp2, xdw->win, newgc, 0, 0, tex_height, tex_length, x - (int)tex_height, y - (int)tex_length); break; case GR_DEGREE270: XPutImage(xdw->display, xdw->win, newgc, xi2, 0, 0, x, y, tex_height, tex_length); break; } XFreePixmap(xdw->display, pixtemp1); XFreePixmap(xdw->display, pixtemp2); XDestroyImage(xi1); XDestroyImage(xi2); break; case GR_LASER: if (ps_state == PS_PATH_ON) { fprintf(lp, "S\n"); ps_state = PS_PATH_OFF; } i = 0; j = 0; while (str[i]) { switch (str[i]) { case ')': case '(': case '\\': buff[j++] = '\\'; default: buff[j++] = str[i++]; } } buff[j] = '\0'; switch (rotate) { case GR_DEGREE90: fprintf(lp, "GS %.1f %.1f T %d R 0 0 M (%s) P%d GR\n", scx(x-ydes), scy(y), rotate, buff, 0); break; case GR_DEGREE270: fprintf(lp, "GS %.1f %.1f T %d R 0 0 M (%s) P%d GR\n", scx(x+ydes), scy(y), rotate, buff, 0); break; } break; case GR_PICT: case GR_WMF: case GR_OFF: case GR_DEBUG: break; } } /*********************************************************************** * * FUNCTION: * gr_vert_text() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Add vertical text. */ void gr_vert_text(int x, int y, char *str, int just, int font, int delta) { int length; int height; int ys, xmid; int i, j; int ydes; length = strlen(str); set_font(font); height = gr_txheight(font); ydes = gr_txdescent(font); y -= ydes; switch(just) { case GR_TOP: ys = 0; break; case GR_CENTER: ys = ((length * gr_txheight(font)) + ((length - 1) * delta)) / 2; break; case GR_BOTTOM: ys = (length * gr_txheight(font)) + ((length - 1) * delta); break; } ys -= gr_txheight(font); /* text is referenced by the bottom */ switch (gr_state) { case GR_SCREEN: j = length; for (i = 0; i < j; i++) { xmid = char_mid(str); XDrawString(xdw->display, xdw->win, xdw->gc, x+xmid, y-ys+((height+delta)*i), str++, 1); } xo = x; yo = y; break; case GR_LASER: xmid = gr_txwidth(font)/2; if (ps_state == PS_PATH_ON) { (void)fprintf(lp, "S\n"); ps_state = PS_PATH_OFF; } for (i = 0; str[i]; i++) { if ((str[i] == '(') || (str[i] == ')') || (str[i] == '\\')) { (void)fprintf(lp, "%.1f %.1f M (\\%c) P%d\n", scx(x+xmid), scy(y - ys + ((height+delta)*i)), str[i], 1); } else { (void)fprintf(lp, "%.1f %.1f M (%c) P%d\n", scx(x+xmid), scy(y - ys + ((height+delta)*i)), str[i], 1); } } xo = x; yo = y; break; case GR_PICT: xmid = char_mid(str); pict_cmd(PICT_LONGTEXT); pict_i16(psc(y - ys)); pict_i16(psc(x + xmid)); pict_set(1, 1); pict_set(*(str++), 1); for (j = 1; j < length; ++j) { pict_cmd(PICT_DVTEXT); pict_set(psc(height + delta), 1); pict_set(1, 1); pict_set(*(str++), 1); } pict_out(); break; case GR_WMF: case GR_OFF: case GR_DEBUG: break; } } /*********************************************************************** * * FUNCTION: * gr_strwidth() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Find the width of the string in pixels. */ int gr_strwidth(char *str, int font) { int width; /* width of string */ int len; /* character count of string */ len = strlen(str); screen_font(font); if ((xdw == NULL) || (xdw->display == NULL)) { width = 0; while (*str != '\0') { width += font_metrics[cur_font.index].cwidths[(unsigned char) *str]; ++str; } } else { width = XTextWidth(cur_font.font_struct, str, len); } return(width); } /*********************************************************************** * * FUNCTION: * gr_txwidth() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Find the maximum width of the specified font. */ int gr_txwidth(int font) { int width; screen_font(font); if ((xdw == NULL) || (xdw->display == NULL)) { width = font_metrics[cur_font.index].width; } else { width = cur_font.font_struct->max_bounds.width; } return width; } /*********************************************************************** * * FUNCTION: * gr_txheight() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Find the maximum height of the font. */ int gr_txheight(int font) { int height; /* height of font */ screen_font(font); if ((xdw == NULL) || (xdw->display == NULL)) { height = font_metrics[cur_font.index].height; } else { height = cur_font.font_struct->ascent + cur_font.font_struct->descent; } return height; } /*********************************************************************** * * FUNCTION: * gr_txdescent() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Find the descent of the font. */ int gr_txdescent(int font) { int descent; screen_font(font); if ((xdw == NULL) || (xdw->display == NULL)) { descent = font_metrics[cur_font.index].descent; } else { descent = cur_font.font_struct->descent; } return descent; } /*********************************************************************** * * FUNCTION: * gr_txascent() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Find the ascent of the font. */ int gr_txascent(int font) { int ascent; screen_font(font); if ((xdw == NULL) || (xdw->display == NULL)) { ascent = font_metrics[cur_font.index].ascent; } else { ascent = cur_font.font_struct->ascent; } return ascent; } /*********************************************************************** * * FUNCTION: * find_color_black() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Allocate color, and default to black if unavailable. */ static unsigned int find_color_black(char *cname) { struct color_list { char *cname; int index; struct color_list *nxtptr; }; static struct color_list *clrorg; /* origin of color list */ struct color_list *clrptr; /* local index */ int index; Colormap cmap; XColor color; index = -1; for (clrptr = clrorg; clrptr != NULL; clrptr = clrptr->nxtptr) { if (!strcmp(cname, clrptr->cname)) { index = clrptr->index; break; } } if (index < 0) { cmap = DefaultColormap(xdw->display, xdw->screen); index = (xdw->iscolor && XParseColor(xdw->display, cmap, cname, &color) && XAllocColor(xdw->display, cmap, &color)) ? color.pixel : BlackPixel(xdw->display, xdw->screen); clrptr = (struct color_list *)malloc(sizeof(struct color_list)); clrptr->cname = strcpy(malloc(strlen(cname) + 1), cname); clrptr->index = index; clrptr->nxtptr = clrorg; clrorg = clrptr; } return index; } /*********************************************************************** * * FUNCTION: * gr_set_color() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Set foreground color. */ void gr_set_color(char *cname, int grayscale) { switch (gr_state) { case GR_SCREEN: XSetForeground(xdw->display, xdw->gc, find_color_black(cname)); break; case GR_LASER: /* * the grayscale is defined so that 0 = white, 100 = black * in PostScript, 1.0 = white, 0.0 = black */ (void)fprintf(lp, "%.2f setgray\n", 0.01 * (float)(100 - grayscale)); break; case GR_PICT: case GR_WMF: case GR_OFF: case GR_DEBUG: break; } } /*********************************************************************** * * FUNCTION: * gr_image() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * Graph image */ void gr_image(int x, int y, GRBitmap *fsimage, GRBitmap *rdimage, int scale) { int i, k; /* text indices */ int length; /* length of image on bytes */ char out[80]; /* output buffer */ static char hex[16] = { /* bitmap hex to ascii conversion */ 'F', '7', 'B', '3', 'D', '5', '9', '1', 'E', '6', 'A', '2', 'C', '4', '8', '0' }; Pixmap temp_data; /* 1d pixmap for image */ switch(gr_state) { /* clear image data space */ case GR_SCREEN: temp_data = XCreatePixmapFromBitmapData(xdw->display, xdw->win, rdimage->bits, rdimage->width, rdimage->height, 1, 0, 1); XCopyPlane(xdw->display, temp_data, xdw->win, xdw->gc, 0, 0, rdimage->width, rdimage->height, x, y, 1); XFreePixmap(xdw->display, temp_data); break; case GR_LASER: if (ps_state==PS_PATH_ON) { (void)fprintf(lp, "S\n"); } (void)fprintf(lp, "gsave /picstr 39 string def %.1f %.1f translate\n", scx(x), scy(y + fsimage->height / scale)); (void)fprintf(lp, "%.1f %.1f scale %d %d 1 [%d 0 0 -%d 0 %d]\n", scx(fsimage->width / scale ), scx(fsimage->height / scale), fsimage->width, fsimage->height, fsimage->width, fsimage->height, fsimage->height);; (void)fprintf(lp, "{currentfile picstr readhexstring pop} image\n"); length = fsimage->height * ((fsimage->width - 1) / 8 + 1); k = 0; for (i = 0; i < length; i++) { out[k++] = hex[(*(fsimage->bits + i)) & 0xf]; out[k++] = hex[((*((fsimage->bits + i))) >> 4) & 0xf]; if (k == 78) { out[k] = '\0'; (void)fprintf(lp, "%s\n", out); k = 0; } } if (k) { while (k < 78) out[k++] = '0'; out[k] = '\0'; (void)fprintf(lp, "%s\n", out); } (void)fprintf(lp, "grestore\n"); break; case GR_PICT: case GR_WMF: case GR_OFF: break; case GR_DEBUG: /* * full size image */ fprintf(debug_fp, " {\n\tchar fsbits[] = {"); length = fsimage->height * ((fsimage->width - 1) / 8 + 1); for(i = 0; i < length; i++) { if ((i % 11) == 0) { fprintf(debug_fp, "\n\t "); } else { fprintf(debug_fp, " "); } fprintf(debug_fp, "0x%02x", fsimage->bits[i] & 0xff); if (i < length - 1) { fprintf(debug_fp, ","); } } fprintf(debug_fp, "\n\t};\n\tGRBitmap fsimage = { %d, %d, fsbits };\n", fsimage->width, fsimage->height); /* * reduced image */ fprintf(debug_fp, "\tchar rdbits[] = {"); length = rdimage->height * ((rdimage->width - 1) / 8 + 1); for(i = 0; i < length; i++) { if ((i % 11) == 0) { fprintf(debug_fp, "\n\t "); } else { fprintf(debug_fp, " "); } fprintf(debug_fp, "0x%02x", rdimage->bits[i] & 0xff); if (i < length - 1) { fprintf(debug_fp, ","); } } fprintf(debug_fp, "\n\t};\n\tGRBitmap rdimage = { %d, %d, rdbits };\n", rdimage->width, rdimage->height); /* * command */ fprintf(debug_fp, "\n\tgr_image(%d, %d, &fsimage, &rdimage, %d);\n" " }\n", x, y, scale); break; } } /*********************************************************************** * * FUNCTION: * gr_set_clip() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * set graph clip region */ void gr_set_clip(int x, int y, int dx, int dy, Region orig_clip_region) { XRectangle rectangle; switch(gr_state) { /* clear image data space */ case GR_SCREEN: save_clip_region = orig_clip_region; rectangle.x = x; rectangle.y = y; rectangle.width = dx; rectangle.height = dy; if (sub_region == NULL) sub_region = XCreateRegion(); if (sub_region2 == NULL) sub_region2 = XCreateRegion(); XUnionRectWithRegion(&rectangle, sub_region, sub_region); if (save_clip_region != NULL) { XIntersectRegion(save_clip_region, sub_region, sub_region2); XSetRegion(xdw->display, xdw->gc, sub_region2); } else { XSetRegion(xdw->display, xdw->gc, sub_region); } break; case GR_LASER: /* * the space at the end is important in not * getting the macros concantenated. */ fprintf(lp, "S GS %.1f %.1f M %.1f %.1f RL %.1f %.1f RL %.1f %.1f RL ", scx(x), scy(y), scx(dx), (double)0, (double)0, (double)-dy, scx(-dx), (double)0); fprintf(lp, "C clip N\n"); break; case GR_PICT: case GR_WMF: case GR_OFF: case GR_DEBUG: break; } } /*********************************************************************** * * FUNCTION: * gr_reset_clip() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * reset graph clip region */ void gr_reset_clip(void) { switch(gr_state) { /* clear image data space */ case GR_SCREEN: if (sub_region != NULL) { XDestroyRegion(sub_region); sub_region = NULL; } if (sub_region2 != NULL) { XDestroyRegion(sub_region2); sub_region2 = NULL; } if (save_clip_region != NULL) { XSetRegion(xdw->display, xdw->gc, save_clip_region); save_clip_region = NULL; } break; case GR_LASER: fprintf(lp, "S GR\n"); break; case GR_PICT: case GR_WMF: case GR_OFF: case GR_DEBUG: break; } } /*********************************************************************** * * FUNCTION: * pict_open() * * INPUTS: * file - (char *) output filename * apple_single - (int) type of file * * OUTPUTS: * none * * RETURNS: * 0 - on success * -1 - on failure * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * pict_fp - (FILE *) output file pointer * pict_font - (int) current font * pict_apple_single - (int) type of file * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Open and initialize a Mac PICT file. */ static int pict_open(char *name, int apple_single) { if ((pict_fp = fopen(name, "w")) == NULL) { return -1; } if (out_buffer == NULL) { out_avail = BATCH_SIZE; out_buffer = (char *)malloc(out_avail); } out_len = 0; pict_apple_single = apple_single; pict_font = -1; if (pict_apple_single) { /* * start Apple Single header */ pict_i32(APPLE_SINGLE_MAGIC); pict_i32(APPLE_SINGLE_VERSION); pict_set(0, 16); pict_i16(2); /* number of entries */ pict_i32(APPLE_SINGLE_FINDER_INFO); pict_i32(50); /* offset */ pict_i32(32); /* length */ pict_i32(APPLE_SINGLE_DATA_FORK); pict_i32(82); /* offset */ pict_i32(0); /* length of PICT data (fix later) */ pict_str("PICT????", 8); pict_set(0, 24); pict_out(); } /* * start PICT file */ pict_set(0, 512); pict_out(); pict_i16(0); /* length of PICT data (fix later) */ pict_i16(0); pict_i16(0); pict_i16(psc(p_height)); pict_i16(psc(p_width)); pict_cmd(PICT_VERSION); pict_set(1, 1); pict_cmd(PICT_CLIP); pict_i16(10); pict_i16(0); pict_i16(0); pict_i16(psc(p_height)); pict_i16(psc(p_width)); pict_cmd(PICT_PNMODE); pict_i16(9); /* patOr */ pict_out(); return 0; } /*********************************************************************** * * FUNCTION: * pict_cmd() * * INPUTS: * val - (int) number to output * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * pict_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Write a command to the output buffer. */ static void pict_cmd(int val) { if (out_len + 1 > out_avail) { out_avail += BATCH_SIZE; out_buffer = (char *)realloc(out_buffer, out_avail); } out_buffer[out_len++] = val & 0xff; } /*********************************************************************** * * FUNCTION: * pict_i16() * * INPUTS: * val - (int) number to output * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * pict_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Write a 16 bit integer to the output buffer. */ static void pict_i16(int val) { if (out_len + 2 > out_avail) { out_avail += BATCH_SIZE; out_buffer = (char *)realloc(out_buffer, out_avail); } out_buffer[out_len++] = (val >> 8) & 0xff; out_buffer[out_len++] = val & 0xff; } /*********************************************************************** * * FUNCTION: * pict_i32() * * INPUTS: * val - (int) number to output * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * pict_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Write a 32 bit integer to the output buffer. */ static void pict_i32(long val) { if (out_len + 4 > out_avail) { out_avail += BATCH_SIZE; out_buffer = (char *)realloc(out_buffer, out_avail); } out_buffer[out_len++] = (val >> 24) & 0xff; out_buffer[out_len++] = (val >> 16) & 0xff; out_buffer[out_len++] = (val >> 8) & 0xff; out_buffer[out_len++] = val & 0xff; } /*********************************************************************** * * FUNCTION: * pict_str() * * INPUTS: * ptr - (char *) pointer to string * len - (int) length of string * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * pict_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Write a string to the metafile buffer. */ static void pict_str(char *ptr, int len) { if (out_len + len > out_avail) { out_avail = (((out_len + len - 1) / BATCH_SIZE) + 1) * BATCH_SIZE; out_buffer = (char *)realloc(out_buffer, out_avail); } memcpy(out_buffer + out_len, ptr, (unsigned int)len); out_len += len; } /*********************************************************************** * * FUNCTION: * pict_set() * * INPUTS: * val - (int) value to set * len - (int) length to set * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * pict_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Repeat set a value to the output string. */ static void pict_set(int val, int len) { if (out_len + len > out_avail) { out_avail = (((out_len + len - 1) / BATCH_SIZE) + 1) * BATCH_SIZE; out_buffer = (char *)realloc(out_buffer, out_avail); } memset(out_buffer + out_len, val, (unsigned int)len); out_len += len; } /*********************************************************************** * * FUNCTION: * pict_out() * * INPUTS: * none * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * pict_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * out_buffer - (char *) output buffer * out_len - (long) length of current record * * DESCRIPTION: * Output the metafile buffer. */ static void pict_out(void) { fwrite(out_buffer, 1, out_len, pict_fp); out_len = 0; } /*********************************************************************** * * FUNCTION: * pict_close() * * INPUTS: * none * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * pict_fp - (FILE *) output file pointer * * DESCRIPTION: * Close the metafile. */ static void pict_close(void) { long loc; /* * end PICT file */ pict_cmd(PICT_END); pict_out(); /* * get length of file * * data_len = loc - 82; * pict_len = data_len - 512; */ loc = ftell(pict_fp); if (pict_apple_single) { /* * fix data length in Apple Single header */ fseek(pict_fp, 46L, 0); loc -= 82L; pict_i32(loc); pict_out(); } /* * fix PICT length in PICT header */ fseek(pict_fp, (pict_apple_single) ? (512L + 82L) : 512L, 0); loc -= 512L; pict_i16(loc & 0xffff); pict_out(); /* * close PICT file */ fclose(pict_fp); pict_fp = NULL; } /*********************************************************************** * * FUNCTION: * wmf_open() * * INPUTS: * file - (char *) output filename * * OUTPUTS: * none * * RETURNS: * 0 - on success * -1 - on failure * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * wmf_fp - (FILE *) output file pointer * wmf_size - (long) output file size * wmf_maxrec - (long) maximum record size * wmf_font - (int) current font * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Open and initialize a Windows Metafile. */ static int wmf_open(char *name) { short inch; short cksum; if ((wmf_fp = fopen(name, "wb")) == NULL) { return -1; } if (out_buffer == NULL) { out_avail = BATCH_SIZE; out_buffer = (char *)malloc(out_avail); } wmf_size = 9; wmf_maxrec = 0; inch = (p_mode & GR_EXPAND) ? 100 : 75; cksum = 0x9ac6 ^ 0xcdd7 ^ p_width ^ p_height ^ inch; out_len = 0; wmf_i32((int)0x9ac6cdd7); /* magic number */ wmf_i16(0); /* hmf (reserved) */ wmf_i16(0); /* left */ wmf_i16(0); /* top */ wmf_i16(p_width); /* right */ wmf_i16(p_height); /* bottom */ wmf_i16(inch); /* inch */ wmf_i32(0); /* reserved */ wmf_i16(cksum); /* checksum */ wmf_i16(1); /* type */ wmf_i16(9); /* header size */ wmf_i16(0x300); /* version */ wmf_i32(0); /* size */ wmf_i16(3); /* no. objects */ wmf_i32(0); /* max record */ wmf_i16(0); /* no. parameters */ fwrite(out_buffer, 1, out_len, wmf_fp); wmf_cmd(WMF_SETMAPMODE); wmf_i16(8); wmf_out(); wmf_cmd(WMF_SETWINDOWORG); wmf_i16(0); wmf_i16(0); wmf_out(); wmf_cmd(WMF_SETWINDOWEXT); wmf_i16(p_height); wmf_i16(p_width); wmf_out(); wmf_cmd(WMF_CREATEPENINDIRECT); wmf_i16(0); wmf_i16(1); wmf_i16(0); wmf_i16(0); wmf_i16(0); wmf_out(); wmf_cmd(WMF_SELECTOBJECT); wmf_i16(0); wmf_out(); wmf_font = GR_HELVETICA | 10; wmf_cmd(WMF_CREATEFONTINDIRECT); wmf_i16(-10); wmf_i16(0); wmf_i16(0); wmf_i16(0); wmf_i16(400); wmf_i16(0); wmf_i16(0); wmf_i16(0); wmf_i16(8192); wmf_str("Arial", (int)strlen("Arial") + 1); wmf_out(); wmf_cmd(WMF_SELECTOBJECT); wmf_i16(1); wmf_out(); wmf_cmd(WMF_CREATEBRUSHINDIRECT); wmf_i16(0); wmf_i16(0); wmf_i16(0); wmf_i16(0); wmf_out(); wmf_cmd(WMF_SELECTOBJECT); wmf_i16(2); wmf_out(); return 0; } /*********************************************************************** * * FUNCTION: * wmf_cmd() * * INPUTS: * val - (int) number to output * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * wmf_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * wmf_fp - (FILE *) output file pointer * wmf_size - (long) output file size * wmf_maxrec - (long) maximum record size * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Write a command to the metafile buffer. */ static void wmf_cmd(int val) { out_len = 4; out_buffer[out_len++] = val & 0xff; out_buffer[out_len++] = (val >> 8) & 0xff; } /*********************************************************************** * * FUNCTION: * wmf_i16() * * INPUTS: * val - (int) number to output * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * wmf_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * wmf_fp - (FILE *) output file pointer * wmf_size - (long) output file size * wmf_maxrec - (long) maximum record size * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Write a 16 bit integer to the metafile buffer. */ static void wmf_i16(int val) { if (out_len + 2 > out_avail) { out_avail += BATCH_SIZE; out_buffer = (char *)realloc(out_buffer, out_avail); } out_buffer[out_len++] = val & 0xff; out_buffer[out_len++] = (val >> 8) & 0xff; } /*********************************************************************** * * FUNCTION: * wmf_i32() * * INPUTS: * val - (int) number to output * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * wmf_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * wmf_fp - (FILE *) output file pointer * wmf_size - (long) output file size * wmf_maxrec - (long) maximum record size * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Write a 32 bit integer to the metafile buffer. */ static void wmf_i32(long val) { if (out_len + 4 > out_avail) { out_avail += BATCH_SIZE; out_buffer = (char *)realloc(out_buffer, out_avail); } out_buffer[out_len++] = val & 0xff; out_buffer[out_len++] = (val >> 8) & 0xff; out_buffer[out_len++] = (val >> 16) & 0xff; out_buffer[out_len++] = (val >> 24) & 0xff; } /*********************************************************************** * * FUNCTION: * wmf_str() * * INPUTS: * ptr - (char *) pointer to string * len - (int) length of string * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * wmf_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * wmf_fp - (FILE *) output file pointer * wmf_size - (long) output file size * wmf_maxrec - (long) maximum record size * out_buffer - (char *) output buffer * out_avail - (int) size of output buffer * out_len - (long) length of current record * * DESCRIPTION: * Write a string to the metafile buffer. */ static void wmf_str(char *ptr, int len) { if (out_len + len > out_avail) { out_avail = (((out_len + len - 1) / BATCH_SIZE) + 1) * BATCH_SIZE; out_buffer = (char *)realloc(out_buffer, out_avail); } memcpy(out_buffer + out_len, ptr, (unsigned int)len); out_len += len + (len % 2); } /*********************************************************************** * * FUNCTION: * wmf_out() * * INPUTS: * none * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * wmf_fp - (FILE *) output file pointer * * EXTERNALLY MODIFIED: * wmf_size - (long) output file size * wmf_maxrec - (long) maximum record size * out_buffer - (char *) output buffer * * DESCRIPTION: * Output the metafile buffer. */ static void wmf_out(void) { long len; len = out_len / 2; out_buffer[0] = len & 0xff; out_buffer[1] = (len >> 8) & 0xff; out_buffer[2] = (len >> 16) & 0xff; out_buffer[3] = (len >> 24) & 0xff; fwrite(out_buffer, 1, out_len, wmf_fp); wmf_size += out_len / 2; if (wmf_maxrec < (long)out_len / 2) wmf_maxrec = out_len / 2; } /*********************************************************************** * * FUNCTION: * wmf_close() * * INPUTS: * none * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * wmf_size - (long) output file size * wmf_maxrec - (long) maximum record size * * EXTERNALLY MODIFIED: * wmf_fp - (FILE *) output file pointer * * DESCRIPTION: * Close the metafile. */ static void wmf_close(void) { wmf_cmd(0); wmf_out(); out_len = 0; wmf_i32(wmf_size); fseek(wmf_fp, 28L, 0); fwrite(out_buffer, 1, 4, wmf_fp); out_len = 0; wmf_i32(wmf_maxrec); fseek(wmf_fp, 34L, 0); fwrite(out_buffer, 1, 4, wmf_fp); fclose(wmf_fp); }