Charles.Forsyth20060303a828770d19 years agoHistory
1536 lines · 36.9 KB · Brainfuck
RawDownload
implement Pdriver; include "sys.m";	sys: Sys;include "draw.m";	draw: Draw;	Display, Font, Rect, Point, Image, Screen: import draw;include "bufio.m";	bufio: Bufio;	Iobuf: import bufio;include "print.m";	Printer: import Print;include "scaler.m";	scaler: Scaler;  K: con 0;C: con 1;M: con 2;Y: con 3;Clight: con 4;Mlight: con 5; HPTRUE: con 1;HPFALSE: con 0;TRUE: con 1;FALSE: con 0; # RGB pixel RGB: adt {	r, g, b: byte;};  # KCMY pixel KCMY: adt {	k, c, m, y: byte;};   DitherParms: adt {	fNumPix: int;	fInput: array of byte;	fErr: array of int;	fSymmetricFlag: int;	fFEDRes: array of int;	fRasterEvenOrOdd: int;	fHifipe: int;	fOutput1, fOutput2, fOutput3: array of byte;}; # magic and wondrous HP colour mapsmap1: array of KCMY;map2: array of KCMY; ABSOLUTE: con 1;RELATIVE: con 0; Compression := 1; DEBUG := 0;stderr: ref Sys->FD;outbuf: ref Iobuf; ESC: con 27; # Palettes for Simple_Color PALETTE_RGB: con 3;PALETTE_CMY: con -3;PALETTE_KCMY: con -4;PALETTE_K: con 1;  # Initialization init(debug: int){	sys = load Sys Sys->PATH;	stderr = sys->fildes(2);	draw = load Draw Draw->PATH;	bufio = load Bufio Bufio->PATH;	scaler = load Scaler Scaler->PATH;	if (scaler == nil) fatal("Failed to load Scaler module");	DEBUG = debug;}  # Return printable area in pixels printable_pixels(p: ref Printer): (int, int){	HMARGIN: con 0.6;	WMARGIN: con 0.3;	winches := p.popt.paper.width_inches - 2.0*WMARGIN;	hinches := p.popt.paper.height_inches - 2.0*HMARGIN;	wres := real p.popt.mode.resx;	hres := real p.popt.mode.resy;		(x, y) := (int (winches*wres), int (hinches*hres)); 	if (p.popt.orientation == Print->PORTRAIT)		return (x, y);	return (y, x);}   # Send image to printer MASK := array[] of {byte 1, byte 3, byte 15, byte 255, byte 255};SHIFT := array[] of {7, 6, 4, 0};GSFACTOR := array[] of {255.0, 255.0/3.0, 255.0/7.0, 1.0, 1.0};lastp : ref Printer; Refint: adt {	value: int;}; watchdog(cancel: chan of int, cancelled: ref Refint){	<- cancel;	cancelled.value = 1;} sendimage(p: ref Printer, pfd: ref Sys->FD, display: ref Draw->Display, im: ref Draw->Image, width: int, lmargin: int, cancel: chan of int): int{	grppid := sys->pctl(Sys->NEWPGRP, nil);	cancelled := ref Refint(0);	spawn watchdog(cancel, cancelled); 	outopen(pfd);	dbg(sys->sprint("image depth=%d from %d,%d to %d,%d\n", im.depth, im.r.min.x, im.r.min.y, im.r.max.x, im.r.max.y));	if (p != lastp) {		(map1, map2) = readmaps(p);		lastp = p;	} 	bpp := im.depth;	linechan := chan of array of int;	if (p.popt.orientation == Print->PORTRAIT)		InputWidth := im.r.max.x-im.r.min.x;	else		InputWidth = im.r.max.y-im.r.min.y;	AdjustedInputWidth := (InputWidth+7) - ((InputWidth+7) % 8);	dbg(sys->sprint("bpp=%d, InputWidth=%d, AdjustedInputWidth=%d\n",						 bpp, InputWidth, AdjustedInputWidth));	if (p.popt.orientation == Print->PORTRAIT)		spawn row_by_row(im, linechan, AdjustedInputWidth);	else		spawn rotate(im, linechan, AdjustedInputWidth);	DesiredOutputWidth := AdjustedInputWidth;	if (width > AdjustedInputWidth)		DesiredOutputWidth = width;	ScaledWidth := 8*((DesiredOutputWidth)/8);	mode := p.popt.mode;	Nplanes := 4;	if (map2 != nil)		Nplanes += 2;	Contone := array[Nplanes] of array of byte;	ColorDepth := array[Nplanes] of int;	ColorDepth[K] = mode.blackdepth;	for (col:=1; col<Nplanes; col++)		ColorDepth[col] = mode.coldepth;	OutputWidth := array[Nplanes] of int;	fDitherParms := array[Nplanes] of DitherParms;	ErrBuff := array[Nplanes] of array of int;	ColorPlane := array[Nplanes] of array of array of array of byte;	MixedRes := 0;	BaseResX := mode.resx;	BaseResY := mode.resy;	ResBoost := BaseResX / BaseResY;	ResolutionX := array[Nplanes] of int;	ResolutionY := array[Nplanes] of int;	ResolutionX[K] = mode.resx*mode.blackresmult;	ResolutionY[K] = mode.resy*mode.blackresmult;	for (col=1; col<Nplanes; col++) {		ResolutionX[col] = mode.resx;		ResolutionY[col] = mode.resy;	}	NumRows := array[Nplanes] of int;	for (j:=0; j<Nplanes; j++) {		if (ResolutionX[j] != ResolutionX[K])			MixedRes++;		if (MixedRes)			# means res(K) !+ res(C,M,Y)			NumRows[j] = ResolutionX[j] / BaseResX;		else			NumRows[j]=1;		OutputWidth[j]= ScaledWidth * NumRows[j] * ResBoost;		PlaneSize:= OutputWidth[j]/8;		Contone[j] = array[OutputWidth[j]] of byte;		ColorPlane[j] = array[NumRows[j]] of array of array of  byte;		for (jj:=0; jj<NumRows[j]; jj++) {			ColorPlane[j][jj] = array[ColorDepth[j]] of array of  byte;			for (jjj:=0; jjj<ColorDepth[j]; jjj++) {				ColorPlane[j][jj][jjj] = array[PlaneSize] of byte;			}		}		ErrBuff[j] = array[OutputWidth[j]+2] of {* => 0};	} 	pcl_startjob(p);	if (p.popt.paper.hpcode != "")		PCL_Page_Size(p.popt.paper.hpcode);	PCL_Move_CAP_H_Units(lmargin*300/BaseResX, ABSOLUTE);	PCL_Configure_Raster_Data4(BaseResX, BaseResY, ColorDepth);	PCL_Source_Raster_Width(ScaledWidth);	PCL_Compression_Method(Compression);	PCL_Start_Raster(1);	cmap1 := setup_color_map(display, map1, im.depth);	if (map2 != nil)		cmap2 := setup_color_map(display, map2, im.depth);	numerator, denominator: int;	if ((ScaledWidth % AdjustedInputWidth)==0) {		numerator = ScaledWidth / AdjustedInputWidth;		denominator = 1;	} else {		numerator = ScaledWidth;		denominator = AdjustedInputWidth;	}	rs := scaler->init(DEBUG, AdjustedInputWidth, numerator, denominator);	rasterno := 0;	col_row: array of int;	eof := 0; 	while (!eof) {		col_row = <- linechan;		if (col_row == nil)			eof++;		scaler->rasterin(rs, col_row);		while ((scaled_col_row := scaler->rasterout(rs)) != nil) {			rasterno++;			fRasterOdd := rasterno & 1;			kcmy_row := SimpleColorMatch(cmap1, scaled_col_row);			if (DEBUG) {				dbg("Scaled Raster line:");				for (q:=0; q<len scaled_col_row; q++) {					(r, g, b) := display.cmap2rgb(scaled_col_row[q]);					dbg(sys->sprint("%d rgb=(%d,%d,%d) kcmy=(%d,%d,%d,%d)\n", int scaled_col_row[q],						r, g, b, int kcmy_row[q].k, int kcmy_row[q].c, int kcmy_row[q].m, int kcmy_row[q].y));				}				dbg("\n");			}			Contone_K := Contone[K];			Contone_C := Contone[C];			Contone_M := Contone[M];			Contone_Y := Contone[Y];			for (ii:=0; ii<len Contone[K]; ii++) {				kcmy := kcmy_row[ii];				Contone_K[ii] = kcmy.k;				Contone_C[ii] = kcmy.c;				Contone_M[ii] = kcmy.m;				Contone_Y[ii] = kcmy.y;			}			if (map2 != nil) {		# For lighter inks				kcmy_row_light := SimpleColorMatch(cmap2, scaled_col_row);				Contone_Clight := Contone[Clight];				Contone_Mlight := Contone[Mlight];				for (ii=0; ii<len Contone[Clight]; ii++) {					kcmy := kcmy_row_light[ii];					Contone_Clight[ii] = kcmy.c;					Contone_Mlight[ii] = kcmy.m;				}			} 			for (i:=0; i< Nplanes; i++) {# Pixel multiply here!!				fDitherParms[i].fNumPix = OutputWidth[i];				fDitherParms[i].fInput = Contone[i];				fDitherParms[i].fErr = ErrBuff[i];#				fDitherParms[i].fErr++;		// serpentine (?)				fDitherParms[i].fSymmetricFlag = 1;#				if (i == K)#					fDitherParms[i].fFEDResPtr = fBlackFEDResPtr;#				else#					fDitherParms[i].fFEDResPtr = fColorFEDResPtr;				fDitherParms[i].fFEDRes = FEDarray;				fDitherParms[i].fRasterEvenOrOdd = fRasterOdd;				fDitherParms[i].fHifipe = ColorDepth[i] > 1;				for (j=0; j < NumRows[i]; j++) {					fDitherParms[i].fOutput1 = ColorPlane[i][j][0];					if (fDitherParms[i].fHifipe)						fDitherParms[i].fOutput2 = ColorPlane[i][j][1];#					dbg(sys->sprint("Dither for Row %d ColorPlane[%d][%d]\n", rasterno, i, j));   					Dither(fDitherParms[i]);				}			} 			FINALPLANE: con 3;#			NfinalPlanes := 4;			for (i=0; i<=FINALPLANE; i++) {				cp_i := ColorPlane[i];				coldepth_i := ColorDepth[i];				finalrow := NumRows[i]-1;				for (j=0; j<=finalrow; j++) {					cp_i_j := cp_i[j];					for (k:=0; k<coldepth_i; k++) {						if (i == FINALPLANE && j == finalrow && k == coldepth_i-1)							PCL_Transfer_Raster_Row(cp_i_j[k]);						else 							PCL_Transfer_Raster_Plane(cp_i_j[k]);						if (cancelled.value) {							PCL_Reset();							outclose();							killgrp(grppid);							return -1;						}					}				}			}		}	}	PCL_End_Raster();	PCL_Reset();	outclose();	killgrp(grppid);	if (cancelled.value)		return -1;#sys->print("dlen %d, clen %d overruns %d\n", dlen, clen, overruns);	return 0;}  # Send text to printer sendtextfd(p: ref Print->Printer, pfd, tfd: ref Sys->FD, pointsize: real, proportional: int, wrap: int): int{	outopen(pfd);	pcl_startjob(p);	if (wrap) PCL_End_of_Line_Wrap(0);	LATIN1: con "0N";	PCL_Font_Symbol_Set(LATIN1);	if (proportional) PCL_Font_Spacing(1);	if (pointsize > 0.0) {		PCL_Font_Height(pointsize);		pitch := 10.0*12.0/pointsize;		PCL_Font_Pitch(pitch);		spacing := int (6.0*12.0/pointsize);		PCL_Line_Spacing(spacing);		dbg(sys->sprint("Text: pointsize %f pitch %f spacing %d\n", pointsize, pitch, spacing));	}	PCL_Line_Termination(3);	inbuf := bufio->fopen(tfd, Bufio->OREAD);	while ((line := inbuf.gets('\n')) != nil) {		ob := array of byte line;		outwrite(ob, len ob);	}	PCL_Reset();	outclose();	return 0;}   # Common PCL start pcl_startjob(p: ref Printer){	PCL_Reset();	if (p.popt.duplex) {		esc("%-12345X@PJL DEFAULT DUPLEX=ON\n");		esc("%-12345X");	}	if (p.popt.paper.hpcode != "")		PCL_Page_Size(p.popt.paper.hpcode);	PCL_Orientation(p.popt.orientation);	PCL_Duplex(p.popt.duplex);}  # Spawned to return  sequence of rotated image rows rotate(im: ref Draw->Image, linechan: chan of array of int, adjwidth: int){	xmin := im.r.min.x;		xmax := im.r.max.x;	InputWidth := xmax - xmin;	rawchan := chan of array of int;	spawn row_by_row(im, rawchan, InputWidth);	r_image := array[InputWidth] of {* => array [adjwidth] of {* => 0}};	r_row := 0;	while ((col_row := <- rawchan) != nil) {		endy := len col_row - 1;		for (i:=0; i<len col_row; i++)			r_image[endy - i][r_row] = col_row[i];		r_row++;	}	for (i:=0; i<len r_image; i++)		linechan <-= r_image[i];	linechan <-= nil;}  # Spawned to return sequence of image rows row_by_row(im: ref Draw->Image, linechan: chan of array of int, adjwidth: int){	xmin := im.r.min.x;		ymin := im.r.min.y;		xmax := im.r.max.x;	ymax := im.r.max.y;	InputWidth := xmax - xmin;	bpp := im.depth;	ld := ldepth(im.depth);	bytesperline := (InputWidth*bpp+7)/8;		rdata := array[bytesperline+10] of byte;	pad0 := array [7] of { * => 0};	for (y:=ymin; y<ymax; y++) {		col_row := array[adjwidth] of int;		rect := Rect((xmin, y), (xmax, y+1));		np := im.readpixels(rect, rdata);		if (np < 0)			fatal("Error reading image\n");		dbg(sys->sprint("Input Raster line %d: np=%d\n  ", y, np));		ind := 0;		mask := MASK[ld];		shift := SHIFT[ld];		col_row[adjwidth-7:] = pad0;	# Pad to adjusted width with white		data := rdata[ind];		for (q:=0; q<InputWidth; q++) {			col := int ((data  >> shift) & mask);			shift -= bpp;			if (shift < 0) {				shift = SHIFT[ld];				ind++;				data = rdata[ind];			}			col_row[q] = col;		}		linechan <-= col_row;	}	linechan <-= nil;}  # PCL output routines  PCL_Reset(){		esc("E");}  PCL_Orientation(value: int){	esc(sys->sprint("&l%dO", value));} PCL_Duplex(value: int){	esc(sys->sprint("&l%dS", value));}  PCL_Left_Margin(value: int){	esc(sys->sprint("&a%dL", value));} PCL_Page_Size(value: string){	esc(sys->sprint("&l%sA", value));}  PCL_End_of_Line_Wrap(value: int){	esc(sys->sprint("&s%dC", value));} PCL_Line_Termination(value: int){	esc(sys->sprint("&k%dG", value));}  PCL_Font_Symbol_Set(value: string){	esc(sys->sprint("(%s", value));}  PCL_Font_Pitch(value: real){	esc(sys->sprint("(s%2.2fH", value));} PCL_Font_Spacing(value: int){	esc(sys->sprint("(s%dP", value));} PCL_Font_Height(value: real){	esc(sys->sprint("(s%2.2fV", value));

Lines 1–500 of 1536.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t