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. Load more
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 maps map1: 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));