Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!usc!sdd.hp.com!hp-pcd!hpcvra.cv.hp.com!rnews!hpcvbbs!akcs.rkb From: akcs.rkb@hpcvbbs.UUCP (Robert Brunner) Newsgroups: comp.sys.handhelds Subject: Re: How does one print out a GROB from a PC? Keywords: GROB, PC printing Message-ID: <27a26d9b:1803.2comp.sys.handhelds;1@hpcvbbs.UUCP> Date: 27 Jan 91 06:40:07 GMT References: <1991Jan24.182436.20395@rick.cs.ubc.ca> <7360058@hpfcso.HP.COM> Lines: 255 I've been meaning to write a program to print out GROBs for some time. Reading the previous posts motivated me to finally do it. The program runs on PC-compatibles under MS-DOS. Some directions for use can be found in the comments for the program. I'm only posting the source code (written in Turbo C) here, but I will also post the executable on hpcvbbs in user.programs. I hope this helps you out. By the way, this program was written and tested in one Saturday afternoon, so it probably includes some bugs (at no extra charge :-)) I'd be interested if others add more options; please get back to me if you do. Robert Brunner brunner@uirvld.csl.uiuc.edu /* / ** grob2eps.c version 1.0 ** Robert Brunner ** 1-26-91 ** ** Translate a GROB to a file which can be copied to an Epson ** printer. The GROB is sent from the HP-48 to the PC using ** ASCII mode. The program is then run with the command: ** ** C>grob2eps grob_file print_file ** ** and the results can be printed with the MS-DOS copy command: ** ** C>copy print_file /b prn ** ** If either filename is omitted, stdin or stdout are used. ** Therefore, another way to execute the command is: ** ** C>grob2eps grob_file >prn ** ** Bugs: ** 1) Specifying PRN for the print_file sends garbage to the printer ** 2) The program is slow as molasses ** ** This program was developed for MS-DOS with Turbo C 2.0, although ** no machine-specific are used, so it may be usable on other ** systems. */ #include #define GROBTYP "GROB" #define ESC 27 main(argc,argv) int argc; char *argv[]; { FILE *fp_in, *fp_out; char ftyp[5], *grobmap; unsigned char *bmap; int realwidth,width,realheight,height,i; long grobsize; /* ** Open files from the command line, or use stdin and stdout */ if (argc>=2) { if ((fp_in=fopen(argv[1],"r"))==NULL) { fprintf(stderr,"Can't open grob file\n"); exit(1); } } else fp_in=stdin; if (argc>=3) { if ((fp_out=fopen(argv[2],"wb"))==NULL) { fprintf(stderr,"Can't open print file\n"); exit(2); } } else fp_out=stdout; /* ** Find the first occurence of GROB and print out this. ** This gets the file pointer past the %%HP junk. */ while (!feof(fp_in)) { fscanf(fp_in,"%5s",ftyp); if (strcmp(GROBTYP,ftyp)==0) break; } if (feof(fp_in)) { fprintf(stderr,"Unexpected eof\n"); exit(3); } /* ** Get the GROB size and the actual grob data ** Notice that the width is rounded up to the next multiple ** of eight, since this is how they are transmitted. ** The real width is saved for printing because the ** lines are completed with 1's */ fscanf(fp_in,"%d %d ",&realwidth,&realheight); if (realwidth%8==0) width=realwidth; else width=((realwidth/8)+1)*8; if (realheight%8==0) height=realheight; else height=((realheight/8)+1)*8; grobmap=(char *)malloc(sizeof(char)*(width/4)*height+1); if (grobmap==NULL) { fprintf(stderr,"GROB too big. Exiting\n"); exit(4); } fgets(grobmap,(width/4)*height+1,fp_in); /* ** Create memory space for a bitmap and clear that memory ** to zero */ bmap=(unsigned char *)malloc(sizeof(char)*width*(height/8)); if (bmap==NULL) { fprintf(stderr,"GROB too big. Exiting\n"); exit(4); } for(i=0;i 0) << j; maptable1[i][j]=((i & 0x2) > 0) << j; maptable2[i][j]=((i & 0x4) > 0) << j; maptable3[i][j]=((i & 0x8) > 0) << j; } /* ** Scan the string, setting the appropriate bits in bmap. ** Note that the MS bit of bmap is the top row. */ bmaprow=0; bitrow=7; bmapcol=0; chptr=grobmap; for(i=0;i='0') && (ch<='9')) val=ch-'0'; else { ch=toupper(ch); if ((ch>='A') && (ch<='F')) val=ch-'A'+10; else val=0; } /* ** Increment the current bit or column at the end of each row */ if (bmapcol>=width) { bmapcol-=width; bitrow--; } if (bitrow<0) { bitrow=7; bmaprow++; } /* ** Skip a bit if there is a zero */ if (val==0) continue; /* ** bitwise-or each pixel column with the appropriate value */ bmap_indx=bmap+bmapcol+width*bmaprow; *bmap_indx++ |= maptable0[val][bitrow]; *bmap_indx++ |= maptable1[val][bitrow]; *bmap_indx++ |= maptable2[val][bitrow]; *bmap_indx |= maptable3[val][bitrow]; } } int print_out(bmap,width,realwidth,height,fp_out) unsigned char *bmap; int width,realwidth,height; FILE *fp_out; { /* ** Print out the bitmap. This routine uses 8-bit single ** density mode for epson printers. On a 9-pin printer ** the output is 60(H)x72(V) dpi. or 60(H)x60(V) dpi on ** a 24-pin printer. A normal size GROB will be pretty ** small, but the calculator can produce larger ones ** which will have better resolution */ int i,j; /* ** Set the line spacing */ fprintf(fp_out,"%c%c%c",ESC,'3',24); for(j=0;j<(height/8);j++) { /* ** Print out one line of points */ fprintf(fp_out,"%c%c%c%c",ESC,'K',realwidth%256,realwidth/256); for(i=0;i