/*****************************************************************************/
/* 				   gentxt.c				     */
/*===========================================================================*/
/* 									     */
/*	--  gentxt generates RayShade program from a character string	     */
/*	    loaded into a Pixmap and then dumped to an image		     */
/* 									     */
/*	--  arg 1:  text to generate (def "A")				     */
/*	    arg 2:  file to place text in (def A[.ray])			     */
/*	    arg 3:  font to use (def "bold courier 24pt ...")		     */
/* 									     */
/*	--  note: it requires a display but does not start any windows	     */
/*	    (awfully peculiar, wouldn't you say)			     */
/* 									     */
/*	--  written 12/21/89 by Ron Sass				     */
/*	    o   12/27/89 added conversion directly to RayShade		     */
/* 									     */
/*   Permission to use, copy, modify, and distribute this software and       */
/*   its documentation for any purpose is hereby granted, provided that      */
/*   no fee beyond distribution costs is charged, the above copyright        */
/*   notice appear in all copies, and that both that copyright notice        */
/*   and this permission notice appear in the supporting documentation.      */
/*   This software is provided "as is" without express or implied warranty.  */
/*                                                                           */
/*****************************************************************************/

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <stdio.h>

/*---------------------------------------------------------------------------*/
int
  main ( argc , argv )
int	argc ;
char	*argv[] ;
{
	/*________________________ X specific vars __________________________*/
	Display		*display;
	int		screen;
	Window		win;
	XFontStruct	*font_info;
	XGCValues	values0, values1 ;
	GC		gc0, gc1 ;
	Pixmap		working ;
	/*__________________________ other vars _____________________________*/
	char	*fontname =
	  "-adobe-courier-bold-r-normal--24-240-75-75-m-150-iso8859-1" ;
	char	*text = "A" ;			      /* text to be produced */
	int	chcount ;			   /* count of chars in text */
	char	*filename = "A" ;			      /* output file */
	char	*display_name = NULL ;
	int	width, height ;
	int	rc ;

	/*....................... check out params ..........................*/
	if( argc>1 )	text = argv[1] ;
	if( argc>2 )	filename = argv[2] ;
	if( argc>3 )	fontname = argv[3] ;

	/*...................... connect to X server ........................*/
	if ( (display=XOpenDisplay(display_name)) == NULL ) {
	    (void)fprintf(stderr,"gentxt: cannot connect to X server %s\n",
	      XDisplayName(display_name));
	    exit( -1 );
	}

	/*.........  get screen size from display structure macro ...........*/
	screen = DefaultScreen(display);

	/*........................ load font info ...........................*/
	font_info = XLoadQueryFont(display,fontname) ;
	if( font_info == NULL ) {
	    (void)fprintf(stderr,"gentxt: Cannot open %s font\n",fontname);
	    exit( -1 );
	}

	/*......... find minimum size for pixmap for entire font ............*/
	chcount = strlen(text) ;
	width = XTextWidth(font_info,text,chcount) ;
	height = font_info->ascent + font_info->descent ;
	printf("w: %d   h: %d\n",width,height) ;

	/*................ create Pixmap for working with ...................*/
	working = XCreatePixmap(display,RootWindow(display,screen),
	  width,height,1) ;

	/*...................... create GC for rect .........................*/
	gc0 = XCreateGC(display, working, 0L, &values0);
	XSetForeground(display, gc0, WhitePixel(display,screen));

	/*...................... create GC for text .........................*/
	gc1 = XCreateGC(display, working, 0L, &values1);
	XSetFont(display, gc1, font_info->fid);
	XSetForeground(display, gc1, BlackPixel(display,screen));

	printf("Drawing Character String... %s\n",text) ;
	XFillRectangle(display,working,gc0,0,0,width-1,height-1) ;
	XDrawString(display,working,gc1,0,font_info->ascent,text,chcount) ;
	XSync(display,0) ;

	/*.............. finally, put this baby into a file .................*/
	printf("Writing to file ... %s.ray\n",filename) ;
	conv_I2Ray(display,filename,working,height,width,text,fontname) ;

	printf("closing display ...\n") ;
	/*......................... close display ...........................*/
	XUnloadFont(display, font_info->fid);
	XFreeGC(display, gc0);
	XFreeGC(display, gc1);
	XFreePixmap(display, working);
	XCloseDisplay(display);
	exit(1);
}
/*===========================================================================*/
/* 			      Image to RayShade				     */
/*===========================================================================*/
/*---------------------------------------------------------------------------*/
/* 				 conv_I2Ray				     */
/*	--  conv_I2Ray converts a Pixmap into a program acceptable to	     */
/*	    RayShade							     */
/*	--  fn is the file name of where to store the RayShade program	     */
/*	--  Mrow is the the height, Mcol is the width			     */
/*	--  the Z axis is fixed at 0					     */
/*---------------------------------------------------------------------------*/
int
  conv_I2Ray ( disp , fn , bitmap , Mrow , Mcol , phrase , fontname )
Display		*disp ;
char		*fn ;
Pixmap		bitmap ;
unsigned int	Mrow, Mcol ;
char		*phrase ;
char		*fontname ;
{
#define	FM	"    poly TXTSUR\t%d %d 0\t%d %d 0\t%d %d 0\t%d %d 0\n"
	register int	row, col, start ;
	char	file[80] ;
	XImage	*image ;
	FILE	*out ;

	strcpy(file,fn) ;
	strcat(file,".ray") ;
	out=fopen(file,"w") ;
	fprintf(out,"/* generated by gentxt: produces text '%s' */\n",phrase) ;
	fprintf(out,"/* bounds are 0,0,0 to %d,%d,0 */\n",Mcol,Mrow) ;
	fprintf(out,"/* font: %s */\n",fontname) ;
	fprintf(out,"/* TXTSUR needs to be defined as some surface */\n") ;
	fprintf(out,"define text_%s\n",fn) ;
	image = XGetImage(disp,bitmap,0,0,Mcol,Mrow,1L,XYPixmap) ;
	for( row=0 ; row<Mrow ; row++ ) {
	    col=0 ;
	    while( col<Mcol ) {
		while( !(XGetPixel(image,col,row)) && col<Mcol )
		    col++ ;
		if( col>=Mcol )	break ;
		start = col ;
		col++ ;
		while( (XGetPixel(image,col,row)) && col<Mcol )
		    col++ ;
		fprintf(out,FM,start,Mrow-row-1,col,Mrow-row-1,col,
		  Mrow-row,start,Mrow-row) ;
	    }
	}

	XDestroyImage(image) ;
	fprintf(out,"/*    grid %d %d 2 */\ndefend\n",Mcol,Mrow) ;
	fclose(out) ;
}
