예제 #1
0
/* Send the page to the printer. */
static int
bj10e_print_page(gx_device_printer *pdev, FILE *prn_stream)
{	int line_size = gx_device_raster((gx_device *)pdev, 0);
        int xres = (int)pdev->x_pixels_per_inch;
        int yres = (int)pdev->y_pixels_per_inch;
        int mode = (yres == 180 ?
                        (xres == 180 ? 11 : 12) :
                        (xres == 180 ? 14 : 16));
        int bytes_per_column = (yres == 180) ? 3 : 6;
        int bits_per_column = bytes_per_column * 8;
        int skip_unit = bytes_per_column * 3;
        byte *in = (byte *)gs_malloc(pdev->memory, 8, line_size, "bj10e_print_page(in)");
        byte *out = (byte *)gs_malloc(pdev->memory, bits_per_column, line_size, "bj10e_print_page(out)");
        int lnum = 0;
        int skip = 0;
        int code = 0;
        int last_row = dev_print_scan_lines(pdev);
        int limit = last_row - bits_per_column;

        if ( in == 0 || out == 0 )
        {	code = gs_note_error(gs_error_VMerror);
                goto fin;
        }

        /* Initialize the printer. */
#ifdef USE_FACTORY_DEFAULTS
        /* Check for U.S. letter vs. A4 paper. */
        fwrite(( pdev->width / pdev->x_pixels_per_inch <= 8.4 ?
                "\033[K\002\000\000\044"	/*A4--DIP switch defaults*/ :
                "\033[K\002\000\004\044"	/*letter--factory defaults*/ ),
               1, 7, prn_stream);
#else
        fwrite("\033[K\002\000\000\044", 1, 7, prn_stream);
#endif

        /* Turn off automatic carriage return, otherwise we get line feeds. */
        fwrite("\0335\000", 1, 3, prn_stream);

        /* Set vertical spacing. */
        fwrite("\033[\\\004\000\000\000", 1, 7, prn_stream);
        fputc(yres & 0xff, prn_stream);
        fputc(yres >> 8, prn_stream);

        /* Set the page length.  This is the printable length, in inches. */
        fwrite("\033C\000", 1, 3, prn_stream);
        fputc((last_row + yres - 1)/yres, prn_stream);

        /* Transfer pixels to printer.  The last row we can print is defined
           by "last_row".  Only the bottom of the print head can print at the
           bottom margin, and so we align the final printing pass.  The print
           head is kept from moving below "limit", which is exactly one pass
           above the bottom margin.  Once it reaches this limit, we make our
           final printing pass of a full "bits_per_column" rows. */
        while ( lnum < last_row )
           {
                byte *in_data;
                byte *in_end = in + line_size;
                byte *out_beg = out;
                byte *out_end = out + bytes_per_column * pdev->width;
                byte *outl = out;
                int bnum;

                /* Copy 1 scan line and test for all zero. */
                code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
                if ( code < 0 ) goto xit;
                /* The mem... or str... functions should be faster than */
                /* the following code, but all systems seem to implement */
                /* them so badly that this code is faster. */
                   {	register const long *zip = (const long *)in_data;
                        register int zcnt = line_size;
                        register const byte *zipb;
                        for ( ; zcnt >= 4 * sizeof(long); zip += 4, zcnt -= 4 * sizeof(long) )
                           {	if ( zip[0] | zip[1] | zip[2] | zip[3] )
                                        goto notz;
                           }
                        zipb = (const byte *)zip;
                        while ( --zcnt >= 0 )
                           {
                                if ( *zipb++ )
                                        goto notz;
                           }
                        /* Line is all zero, skip */
                        lnum++;
                        skip++;
                        continue;
notz:			;
                   }

                /* Vertical tab to the appropriate position.  Note here that
                   we make sure we don't move below limit. */
                if ( lnum > limit )
                    {	skip -= (lnum - limit);
                        lnum = limit;
                    }
                while ( skip > 255 )
                   {	fputs("\033J\377", prn_stream);
                        skip -= 255;
                   }
                if ( skip )
                        fprintf(prn_stream, "\033J%c", skip);

                /* If we've printed as far as "limit", then reset "limit"
                   to "last_row" for the final printing pass. */
                if ( lnum == limit )
                        limit = last_row;
                skip = 0;

                /* Transpose in blocks of 8 scan lines. */
                for ( bnum = 0; bnum < bits_per_column; bnum += 8 )
                   {	int lcnt = min(8, limit - lnum);
                        byte *inp = in;
                        byte *outp = outl;
                        lcnt = gdev_prn_copy_scan_lines(pdev,
                                lnum, in, lcnt * line_size);
                        if ( lcnt < 0 )
                           {	code = lcnt;
                                goto xit;
                           }
                        if ( lcnt < 8 )
                                memset(in + lcnt * line_size, 0,
                                       (8 - lcnt) * line_size);
                        for ( ; inp < in_end; inp++, outp += bits_per_column )
                           {	gdev_prn_transpose_8x8(inp, line_size,
                                        outp, bytes_per_column);
                           }
                        outl++;
                        lnum += lcnt;
                        skip += lcnt;
                   }

                /* Send the bits to the printer.  We alternate horizontal
                   skips with the data.  The horizontal skips are in units
                   of 1/120 inches, so we look at the data in groups of
                   3 columns, since 3/360 = 1/120, and 3/180 = 2/120.  */
                outl = out;
                do
                   {	int count;
                        int n;
                        byte *out_ptr;

                        /* First look for blank groups of columns. */
                        while(outl < out_end)
                           {	n = count = min(out_end - outl, skip_unit);
                                out_ptr = outl;
                                while ( --count >= 0 )
                                   {	if ( *out_ptr++ )
                                                break;
                                   }
                                if ( count >= 0 )
                                        break;
                                else
                                        outl = out_ptr;
                           }
                        if (outl >= out_end)
                                break;
                        if (outl > out_beg)
                           {	count = (outl - out_beg) / skip_unit;
                                if ( xres == 180 ) count <<= 1;
                                fprintf(prn_stream, "\033d%c%c",
                                        count & 0xff, count >> 8);
                           }

                        /* Next look for non-blank groups of columns. */
                        out_beg = outl;
                        outl += n;
                        while(outl < out_end)
                           {	n = count = min(out_end - outl, skip_unit);
                                out_ptr = outl;
                                while ( --count >= 0 )
                                   {	if ( *out_ptr++ )
                                                break;
                                   }
                                if ( count < 0 )
                                        break;
                                else
                                        outl += n;
                           }
                        count = outl - out_beg + 1;
                        fprintf(prn_stream, "\033[g%c%c%c",
                                count & 0xff, count >> 8, mode);
                        fwrite(out_beg, 1, count - 1, prn_stream);
                        out_beg = outl;
                        outl += n;
                   }
                while ( out_beg < out_end );

                fputc('\r', prn_stream);
           }
예제 #2
0
/* since computer-to-printer communication time is often a bottleneck. */
static int
oki4w_print_page(gx_device_printer *pdev, FILE *prn_stream)
{
	int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
	int line_size_words = (line_size + W - 1) / W;
	uint storage_size_words = line_size_words * 8; /* data, out_row, out_row_alt, prev_row */
	word *storage = (ulong *)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), storage_size_words, W,
					   "oki4w_print_page");
	word
	  *data_words,
	  *out_row_words,
	  *out_row_alt_words,
	  *prev_row_words;
#define data ((byte *)data_words)
#define out_row ((byte *)out_row_words)
#define out_row_alt ((byte *)out_row_alt_words)
#define prev_row ((byte *)prev_row_words)
	byte *out_data;
	int x_dpi = pdev->x_pixels_per_inch;
	int y_dpi = pdev->y_pixels_per_inch;
	int y_dots_per_pixel = x_dpi / y_dpi;
	int dpi_code, compress_code;
	int num_rows = dev_print_scan_lines(pdev);

	int out_count;
	int paper_size = oki_paper_size((gx_device *)pdev);
	int code = 0;
	/* bool dup = pdev->Duplex;
	bool dupset = pdev->Duplex_set >= 0; */

	if ( storage == 0 )	/* can't allocate working area */
		return_error(gs_error_VMerror);
	data_words = storage;
	out_row_words = data_words + (line_size_words * 2);
	out_row_alt_words = out_row_words + (line_size_words * 2);
	prev_row_words = out_row_alt_words + (line_size_words * 2);
	/* Clear temp storage */
	memset(data, 0, storage_size_words * W);

	out_data = out_row;

	if (y_dpi == 150) {
		dpi_code = 3;
		compress_code = 2;
	} else if (y_dpi == 300) {
		dpi_code = 5;
		compress_code = 2;
	} else {
		dpi_code = 7;
		compress_code = 2;
	}

	/* Initialize printer. */
/*	if ( pdev->PageCount == 0 ) { */
		/* Put out init string before page. */
		fprintf(prn_stream, "\x1B%%-98765X\x1C\x14\x03\x41i\x10\x1C"
			"\x14\x05\x41\x65%cf%c\x1C\x14\x09\x42\x61%cb\x02\x63"
			"\x01\x65%c\x1C\x7F\x39\x1B&B\x1B&A\x07%c\x01%c"
			"\x01%c%c%c%c\x1B$A",
			dpi_code, dpi_code, 0, 0, 0, paper_size,
			0, dpi_code, dpi_code, 0);
/*	} */

	/* Send each scan line in turn */
	   {	int lnum;
		int num_blank_lines = 0;
		word rmask = ~(word)0 << (-pdev->width & (W * 8 - 1));

		/* Transfer raster graphics. */
		for ( lnum = 0; lnum < num_rows; lnum++ )
		   {	register word *end_data =
				data_words + line_size_words;
			int i;
			code = gdev_prn_copy_scan_lines(pdev, lnum,
						 (byte *)data, line_size);
			if ( code < 0 )
				break;
		   	/* Mask off 1-bits beyond the line width. */
			end_data[-1] &= rmask;
			/* Remove trailing 0s. */
			while ( end_data > data_words && end_data[-1] == 0 )
			  end_data--;
			if ( end_data == data_words )
			   {	/* Blank line */
				num_blank_lines++;
				continue;
			   }

			/* We've reached a non-blank line. */
			/* Put out a spacing command if necessary. */
			if ( num_blank_lines == lnum )
			{	/* We're at the top of a page. */
				/* TODO: skip top_margin lines... */
				/* num_blank_lines += xxx */
				/* Skip blank lines if any */
				if (num_blank_lines > 0) {
					fprintf(prn_stream, "\x1b*B%c%c",
						num_blank_lines & 0xff,
						num_blank_lines >> 8);
				}
			}
			else if ( num_blank_lines != 0 )
			{
				/* Skip blank lines if any */
				fprintf(prn_stream, "\x1b*B%c%c",
					num_blank_lines & 0xff,
					num_blank_lines >> 8);
			}
예제 #3
0
int
dljet_mono_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
			     int num_copies, int dots_per_inch, int features,
			     const char *odd_page_init, const char *even_page_init, bool tumble)
{
    int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
    int line_size_words = (line_size + W - 1) / W;
    uint storage_size_words = line_size_words * 8;	/* data, out_row, out_row_alt, prev_row */
    word *storage;
    word
	*data_words,
	*out_row_words,
	*out_row_alt_words,
	*prev_row_words;
#define data ((byte *)data_words)
#define out_row ((byte *)out_row_words)
#define out_row_alt ((byte *)out_row_alt_words)
#define prev_row ((byte *)prev_row_words)
    byte *out_data;
    int x_dpi = (int)pdev->x_pixels_per_inch;
    int y_dpi = (int)pdev->y_pixels_per_inch;
    int y_dots_per_pixel = dots_per_inch / y_dpi;
    int num_rows = dev_print_scan_lines(pdev);

    int out_count;
    int compression = -1;
    static const char *const from2to3 = "\033*b3M";
    static const char *const from3to2 = "\033*b2M";
    int penalty_from2to3 = strlen(from2to3);
    int penalty_from3to2 = strlen(from3to2);
    int paper_size = gdev_pcl_paper_size((gx_device *) pdev);
    int code = 0;
    bool dup = pdev->Duplex;
    bool dupset = pdev->Duplex_set >= 0;

    if (num_copies != 1 && !(features & PCL_CAN_PRINT_COPIES))
	return gx_default_print_page_copies(pdev, prn_stream, num_copies);
    storage =
	(ulong *)gs_alloc_byte_array(pdev->memory, storage_size_words, W,
				     "hpjet_print_page");
    if (storage == 0)		/* can't allocate working area */
	return_error(gs_error_VMerror);
    data_words = storage;
    out_row_words = data_words + (line_size_words * 2);
    out_row_alt_words = out_row_words + (line_size_words * 2);
    prev_row_words = out_row_alt_words + (line_size_words * 2);
    /* Clear temp storage */
    memset(data, 0, storage_size_words * W);

    /* Initialize printer. */
    if (pdev->PageCount == 0) {
	if (features & HACK__IS_A_LJET4PJL) {
 	    fputs("\033%-12345X@PJL\r\n@PJL ENTER LANGUAGE = PCL\r\n",
  		  prn_stream);
	}
	fputs("\033E", prn_stream);	/* reset printer */
	/* If the printer supports it, set the paper size */
	/* based on the actual requested size. */
	if (features & PCL_CAN_SET_PAPER_SIZE) {
	    fprintf(prn_stream, "\033&l%dA", paper_size);
	}
	/* If printer can duplex, set duplex mode appropriately. */
	if (features & PCL_HAS_DUPLEX) {
	    if (dupset && dup && !tumble)
		fputs("\033&l1S", prn_stream);
       else if (dupset && dup && tumble)
		fputs("\033&l2S", prn_stream);
	    else if (dupset && !dup)
		fputs("\033&l0S", prn_stream);
	    else		/* default to duplex for this printer */
		fputs("\033&l1S", prn_stream);
	}
    }
    /* Put out per-page initialization. */
    if (features & PCL_CAN_SET_PAPER_SIZE){ 
        fprintf(prn_stream, "\033&l%dA", paper_size); 
    } 
    fputs("\033&l0o0l0E", prn_stream);
    if ((features & PCL_HAS_DUPLEX) && dupset && dup)
    {
       /* We are printing duplex, so change margins as needed */
       if ((pdev->PageCount%2)==0)
          fputs(odd_page_init, prn_stream);
       else
          fputs(even_page_init, prn_stream);
    }
    else
        fputs(odd_page_init, prn_stream);
    fprintf(prn_stream, "\033&l%dX", num_copies);	/* # of copies */

    /* End raster graphics, position cursor at top. */
    fputs("\033*rB\033*p0x0Y", prn_stream);

    /* The DeskJet and DeskJet Plus reset everything upon */
    /* receiving \033*rB, so we must reinitialize graphics mode. */
    if (features & PCL_END_GRAPHICS_DOES_RESET) {
	fputs(odd_page_init, prn_stream); /* Assume this does the right thing */
	fprintf(prn_stream, "\033&l%dX", num_copies);	/* # of copies */
    }

    /* Set resolution. */
    fprintf(prn_stream, "\033*t%dR", x_dpi);

    /* Send each scan line in turn */
    {
	int lnum;
	int num_blank_lines = 0;
	word rmask = ~(word) 0 << (-pdev->width & (W * 8 - 1));

	/* Transfer raster graphics. */
	for (lnum = 0; lnum < num_rows; lnum++) {
	    register word *end_data =
	    data_words + line_size_words;

	    code = gdev_prn_copy_scan_lines(pdev, lnum,
					    (byte *) data, line_size);
	    if (code < 0)
		break;
	    /* Mask off 1-bits beyond the line width. */
	    end_data[-1] &= rmask;
	    /* Remove trailing 0s. */
	    while (end_data > data_words && end_data[-1] == 0)
		end_data--;
	    if (end_data == data_words) {	/* Blank line */
		num_blank_lines++;
		continue;
	    }
	    /* We've reached a non-blank line. */
	    /* Put out a spacing command if necessary. */
	    if (num_blank_lines == lnum) {
		/* We're at the top of a page. */
		if (features & PCL_ANY_SPACING) {
		    if (num_blank_lines > 0)
			fprintf(prn_stream, "\033*p+%dY",
				num_blank_lines * y_dots_per_pixel);
		    /* Start raster graphics. */
		    fputs("\033*r1A", prn_stream);
		} else if (features & PCL_MODE_3_COMPRESSION) {
		    /* Start raster graphics. */
		    fputs("\033*r1A", prn_stream);
#if 1				/* don't waste paper */
		    if (num_blank_lines > 0)
			fputs("\033*b0W", prn_stream);
		    num_blank_lines = 0;
#else
		    for (; num_blank_lines; num_blank_lines--)
			fputs("\033*b0W", prn_stream);
#endif
		} else {
		    /* Start raster graphics. */
		    fputs("\033*r1A", prn_stream);
		    for (; num_blank_lines; num_blank_lines--)
			fputs("\033*bW", prn_stream);
		}
	    }
	    /* Skip blank lines if any */
	    else if (num_blank_lines != 0) {
		/*
		 * Moving down from current position causes head motion
		 * on the DeskJet, so if the number of lines is small,
		 * we're better off printing blanks.
		 */
		/*
		 * For Canon LBP4i and some others, <ESC>*b<n>Y doesn't
		 * properly clear the seed row if we are in compression mode
		 * 3.
		 */
		if ((num_blank_lines < MIN_SKIP_LINES && compression != 3) ||
		    !(features & PCL_ANY_SPACING)
		    ) {
		    bool mode_3ns =
			(features & PCL_MODE_3_COMPRESSION) &&
			!(features & PCL_ANY_SPACING);

		    if (mode_3ns && compression != 2) {
			/* Switch to mode 2 */
			fputs(from3to2, prn_stream);
			compression = 2;
		    }
		    if (features & PCL_MODE_3_COMPRESSION) {
			/* Must clear the seed row. */
			fputs("\033*b1Y", prn_stream);
			num_blank_lines--;
		    }
		    if (mode_3ns) {
			for (; num_blank_lines; num_blank_lines--)
			    fputs("\033*b0W", prn_stream);
		    } else {
			for (; num_blank_lines; num_blank_lines--)
			    fputs("\033*bW", prn_stream);
		    }
		} else if (features & PCL3_SPACING) {
		    fprintf(prn_stream, "\033*p+%dY",
			    num_blank_lines * y_dots_per_pixel);
		} else {
		    fprintf(prn_stream, "\033*b%dY",
			    num_blank_lines);
		}
		/* Clear the seed row (only matters for */
		/* mode 3 compression). */
		memset(prev_row, 0, line_size);
	    }
	    num_blank_lines = 0;

	    /* Choose the best compression mode */
	    /* for this particular line. */
	    if (features & PCL_MODE_3_COMPRESSION) {
		/* Compression modes 2 and 3 are both */
		/* available.  Try both and see which one */
		/* produces the least output data. */
		int count3 = gdev_pcl_mode3compress(line_size, data,
						    prev_row, out_row);
		int count2 = gdev_pcl_mode2compress(data_words, end_data,
						    out_row_alt);
		int penalty3 =
		    (compression == 3 ? 0 : penalty_from2to3);
		int penalty2 =
		    (compression == 2 ? 0 : penalty_from3to2);

		if (count3 + penalty3 < count2 + penalty2) {
		    if (compression != 3)
			fputs(from2to3, prn_stream);
		    compression = 3;
		    out_data = out_row;
		    out_count = count3;
		} else {
		    if (compression != 2)
			fputs(from3to2, prn_stream);
		    compression = 2;
		    out_data = out_row_alt;
		    out_count = count2;
		}
	    } else if (features & PCL_MODE_2_COMPRESSION) {
		out_data = out_row;
		out_count = gdev_pcl_mode2compress(data_words, end_data,
						   out_row);
	    } else {
		out_data = data;
		out_count = (byte *) end_data - data;
	    }

	    /* Transfer the data */
	    fprintf(prn_stream, "\033*b%dW", out_count);
	    fwrite(out_data, sizeof(byte), out_count,
		   prn_stream);
	}
    }

    /* end raster graphics and eject page */
    fputs("\033*rB\f", prn_stream);

    /* free temporary storage */
    gs_free_object(pdev->memory, storage, "hpjet_print_page");

    return code;
}
예제 #4
0
/* one scan line at a time */
static int
win_pr2_print_page(gx_device_printer * pdev, FILE * file)
{
    int raster = gdev_prn_raster(pdev);

    /* BMP scan lines are padded to 32 bits. */
    ulong bmp_raster = raster + (-raster & 3);
    ulong bmp_raster_multi;
    int scan_lines, yslice, lines, i;
    int width;
    int depth = pdev->color_info.depth;
    byte *row;
    int y;
    int code = 0;		/* return code */
    MSG msg;
    char dlgtext[32];
    HGLOBAL hrow;
    int ratio = ((gx_device_win_pr2 *)pdev)->ratio;

    struct bmi_s {
	BITMAPINFOHEADER h;
	RGBQUAD pal[256];
    } bmi;

    scan_lines = dev_print_scan_lines(pdev);
    width = (int)(pdev->width - ((dev_l_margin(pdev) + dev_r_margin(pdev) -
				  dev_x_offset(pdev)) * pdev->x_pixels_per_inch));

    yslice = 65535 / bmp_raster;	/* max lines in 64k */
    bmp_raster_multi = bmp_raster * yslice;
    hrow = GlobalAlloc(0, bmp_raster_multi);
    row = GlobalLock(hrow);
    if (row == 0)		/* can't allocate row buffer */
	return_error(gs_error_VMerror);

    /* Write the info header. */

    bmi.h.biSize = sizeof(bmi.h);
    bmi.h.biWidth = pdev->width;	/* wdev->mdev.width; */
    bmi.h.biHeight = yslice;
    bmi.h.biPlanes = 1;
    bmi.h.biBitCount = pdev->color_info.depth;
    bmi.h.biCompression = 0;
    bmi.h.biSizeImage = 0;	/* default */
    bmi.h.biXPelsPerMeter = 0;	/* default */
    bmi.h.biYPelsPerMeter = 0;	/* default */

    StartPage(wdev->hdcprn);
    
    /* Write the palette. */

    if (depth <= 8) {
	int i;
	gx_color_value rgb[3];
	LPRGBQUAD pq;

	bmi.h.biClrUsed = 1 << depth;
	bmi.h.biClrImportant = 1 << depth;
	for (i = 0; i != 1 << depth; i++) {
	    (*dev_proc(pdev, map_color_rgb)) ((gx_device *) pdev,
					      (gx_color_index) i, rgb);
	    pq = &bmi.pal[i];
	    pq->rgbRed = gx_color_value_to_byte(rgb[0]);
	    pq->rgbGreen = gx_color_value_to_byte(rgb[1]);
	    pq->rgbBlue = gx_color_value_to_byte(rgb[2]);
	    pq->rgbReserved = 0;
	}
    } else {
	bmi.h.biClrUsed = 0;
	bmi.h.biClrImportant = 0;
    }

    if (!wdev->nocancel) {
	sprintf(dlgtext, "Printing page %d", (int)(pdev->PageCount) + 1);
	SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PRINTING), dlgtext);
	ShowWindow(wdev->hDlgModeless, SW_SHOW);
    }
    for (y = 0; y < scan_lines;) {
	/* copy slice to row buffer */
	if (y > scan_lines - yslice)
	    lines = scan_lines - y;
	else
	    lines = yslice;
	for (i = 0; i < lines; i++)
	    gdev_prn_copy_scan_lines(pdev, y + i,
			      row + (bmp_raster * (lines - 1 - i)), raster);
	
	if (ratio > 1) {
	    StretchDIBits(wdev->hdcprn, 0, y*ratio, pdev->width*ratio, lines*ratio,
			  0, 0, pdev->width, lines,
			  row,
			  (BITMAPINFO FAR *) & bmi, DIB_RGB_COLORS, SRCCOPY);
	} else {
	    SetDIBitsToDevice(wdev->hdcprn, 0, y, pdev->width, lines,
			      0, 0, 0, lines,
			      row,
			      (BITMAPINFO FAR *) & bmi, DIB_RGB_COLORS);
	}
	y += lines;

	if (!wdev->nocancel) {
	    /* inform user of progress */
	    sprintf(dlgtext, "%d%% done", (int)(y * 100L / scan_lines));
	    SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE), dlgtext);
	}
	/* process message loop */
	while (PeekMessage(&msg, wdev->hDlgModeless, 0, 0, PM_REMOVE)) {
	    if ((wdev->hDlgModeless == 0) || !IsDialogMessage(wdev->hDlgModeless, &msg)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	    }
	}
	if ((!wdev->nocancel) && (wdev->hDlgModeless == 0)) {
	    /* user pressed cancel button */
	    break;
	}
    }

    if ((!wdev->nocancel) && (wdev->hDlgModeless == 0))
	code = gs_error_Fatal;	/* exit Ghostscript cleanly */
    else {
	/* push out the page */
	if (!wdev->nocancel)
	    SetWindowText(GetDlgItem(wdev->hDlgModeless, CANCEL_PCDONE),
			  "Ejecting page...");
	EndPage(wdev->hdcprn);
	if (!wdev->nocancel)
	    ShowWindow(wdev->hDlgModeless, SW_HIDE);
    }

    GlobalUnlock(hrow);
    GlobalFree(hrow);

    return code;
}
예제 #5
0
/* Send the page to the printer. */
static int
coslw_print_page(gx_device_printer * pdev, FILE * prn_stream)
{
    int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
    int line_size_words = (line_size + W - 1) / W;
    uint storage_size_words = line_size_words * 8;	/* data, out_row, out_row_alt, prev_row */
    word *storage = (ulong *) gs_malloc(pdev->memory, storage_size_words, W,
                                        "coslw_print_page");

    word *data_words;
#define data ((byte *)data_words)

    byte *out_data;
    int num_rows = dev_print_scan_lines(pdev);
    int bytes_per_line = 0;
    int out_count;
    int code = 0;

    if (storage == 0)		/* can't allocate working area */
        return_error(gs_error_VMerror);
    data_words = storage;

    /* Clear temp storage */
    memset(data, 0, storage_size_words * W);

    /* Initialize printer. */
    if (pdev->PageCount == 0) {
    }

    /* Put out per-page initialization. */

    /* End raster graphics, position cursor at top. */

    /* Send each scan line in turn */
    {
        int lnum;
        int num_blank_lines = 0;
        word rmask = ~(word) 0 << (-pdev->width & (W * 8 - 1));

        /* Transfer raster graphics. */
        for (lnum = 0; lnum < num_rows; lnum++) {
            register word *end_data =
            data_words + line_size_words;

            code = gdev_prn_copy_scan_lines(pdev, lnum,
                                            (byte *) data, line_size);
            if (code < 0)
                break;
            /* Mask off 1-bits beyond the line width. */
            end_data[-1] &= rmask;
            /* Remove trailing 0s. */
            while (end_data > data_words && end_data[-1] == 0)
                end_data--;
            if (end_data == data_words) {	/* Blank line */
                num_blank_lines++;
                continue;
            }

            /* We've reached a non-blank line. */
            /* Put out a spacing command if necessary. */
            while (num_blank_lines > 0)
            {
                int this_blank = 255;
                if (num_blank_lines < this_blank)
                    this_blank = num_blank_lines;
                fprintf(prn_stream, "\033f\001%c", this_blank);
                num_blank_lines -= this_blank;
            }

            /* Perhaps add compression here later? */
            out_data = data;
            out_count = (byte *) end_data - data;

            /* For 2 inch model, max width is 56 bytes */
            if (out_count > 56)
                out_count = 56;
            /* Possible change the bytes per line */
            if (bytes_per_line != out_count)
            {
                fprintf(prn_stream, "\033D%c", out_count);
                bytes_per_line = out_count;
            }

            /* Transfer the data */
            fputs("\026", prn_stream);
            fwrite(out_data, sizeof(byte), out_count, prn_stream);
        }
    }

    /* eject page */
    fputs("\033E", prn_stream);

    /* free temporary storage */
    gs_free(pdev->memory, (char *)storage, storage_size_words, W, "coslw_print_page");

    return code;
}
예제 #6
0
/* Send the page to the printer. */
static int
sj48_print_page(gx_device_printer *pdev, FILE *prn_stream)
{	int line_size = gx_device_raster((gx_device *)pdev, 0);
        int xres = pdev->x_pixels_per_inch;
        int yres = pdev->y_pixels_per_inch;
        int mode = (yres == 180 ?
                        (xres == 180 ? 39 : 40) :
                        (xres == 180 ? 71 : 72));
        int bytes_per_column = (yres == 180) ? 3 : 6;
        int bits_per_column = bytes_per_column * 8;
        int skip_unit = bytes_per_column * (xres == 180 ? 1 : 2); /* Skips in step of 1/180" */
        byte *in = (byte *)gs_malloc(pdev->memory, 8, line_size, "sj48_print_page(in)");
        byte *out = (byte *)gs_malloc(pdev->memory, bits_per_column, line_size, "sj48_print_page(out)");
        int lnum = 0;
        int skip = 0;
        int skips;
        int code = 0;
        int last_row = dev_print_scan_lines(pdev);
        int limit = last_row - bits_per_column;

        if ( in == 0 || out == 0 )
        {	code = gs_error_VMerror;
                gs_note_error(code);
                goto fin;
        }

        /* Abort if the requested resolution is unsupported. */
        if ((xres !=180 && xres != 360) || (yres !=180 && yres != 360))
        {	code = gs_error_rangecheck;
                gs_note_error(code);
                goto fin;
        }

        /* Initialize the printer. */
        fwrite("\033@\000\000", 1, 4, prn_stream);  /* <Printer reset>, <0>, <0>. */

        /* Transfer pixels to printer.  The last row we can print is defined
           by "last_row".  Only the bottom of the print head can print at the
           bottom margin, and so we align the final printing pass.  The print
           head is kept from moving below "limit", which is exactly one pass
           above the bottom margin.  Once it reaches this limit, we make our
           final printing pass of a full "bits_per_column" rows. */
        while ( lnum < last_row )
           {
                byte *in_data;
                byte *in_end = in + line_size;
                byte *out_beg = out;
                byte *out_end = out + bytes_per_column * pdev->width;
                byte *outl = out;
                int bnum;

                /* Copy 1 scan line and test for all zero. */
                code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
                if ( code < 0 ) goto xit;
                /* The mem... or str... functions should be faster than */
                /* the following code, but all systems seem to implement */
                /* them so badly that this code is faster. */
                   {	register const long *zip = (const long *)in_data;
                        register int zcnt = line_size;
                        register const byte *zipb;
                        for ( ; zcnt >= 4 * sizeof(long); zip += 4, zcnt -= 4 * sizeof(long) )
                           {	if ( zip[0] | zip[1] | zip[2] | zip[3] )
                                        goto notz;
                           }
                        zipb = (const byte *)zip;
                        while ( --zcnt >= 0 )
                           {
                                if ( *zipb++ )
                                        goto notz;
                           }
                        /* Line is all zero, skip */
                        lnum++;
                        skip++;
                        continue;
notz:			;
                   }

                /* Vertical tab to the appropriate position.  Note here that
                   we make sure we don't move below limit. */
                if ( lnum > limit )
                    {	skip -= (limit - lnum);
                        lnum = limit;
                    }

                /* The SJ48 can only skip in steps of 1/180" */
                if (yres == 180) {
                  skips = skip;
                } else {
                  if (skip & 1) {
                    skip--; /* Makes skip even. */
                    lnum--;
                  }
                  skips = skip/2;
                }

                while ( skips > 255 )
                   {	fputs("\033J\377", prn_stream);
                        skips -= 255;
                   }
                if ( skips )
                        fprintf(prn_stream, "\033J%c", skips);

                /* If we've printed as far as "limit", then reset "limit"
                   to "last_row" for the final printing pass. */
                if ( lnum == limit )
                        limit = last_row;
                skip = 0;

                /* Transpose in blocks of 8 scan lines. */
                for ( bnum = 0; bnum < bits_per_column; bnum += 8 )
                   {	int lcnt = min(8, limit - lnum);
                        byte *inp = in;
                        byte *outp = outl;
                        lcnt = gdev_prn_copy_scan_lines(pdev,
                                lnum, in, lcnt * line_size);
                        if ( lcnt < 0 )
                           {	code = lcnt;
                                goto xit;
                           }
                        if ( lcnt < 8 )
                                memset(in + lcnt * line_size, 0,
                                       (8 - lcnt) * line_size);
                        for ( ; inp < in_end; inp++, outp += bits_per_column )
                           {	gdev_prn_transpose_8x8(inp, line_size,
                                        outp, bytes_per_column);
                           }
                        outl++;
                        lnum += lcnt;
                        skip += lcnt;
                   }

                /* Send the bits to the printer.  We alternate horizontal
                   skips with the data.  The horizontal skips are in units
                   of 1/180 inches, so we look at the data in groups of
                   1 or 2 columns depending on resolution (controlled
                   by skip_unit).  */
                outl = out;
                do
                   {	int count;
                        int n;
                        byte *out_ptr;

                        /* First look for blank groups of columns. */
                        while(outl < out_end)
                           {	n = count = min(out_end - outl, skip_unit);
                                out_ptr = outl;
                                while ( --count >= 0 )
                                   {	if ( *out_ptr++ )
                                                break;
                                   }
                                if ( count >= 0 )
                                        break;
                                else
                                        outl = out_ptr;
                           }
                        if (outl >= out_end)
                                break;
                        if (outl > out_beg)
                           {	count = (outl - out_beg) / skip_unit;
                                fprintf(prn_stream, "\033\\%c%c",
                                        count & 0xff, count >> 8);
                           }

                        /* Next look for non-blank groups of columns. */
                        out_beg = outl;
                        outl += n;
                        while(outl < out_end)
                           {	n = count = min(out_end - outl, skip_unit);
                                out_ptr = outl;
                                while ( --count >= 0 )
                                   {	if ( *out_ptr++ )
                                                break;
                                   }
                                if ( count < 0 )
                                        break;
                                else
                                        outl += n;
                           }
                        count = outl - out_beg;
                        {
                          /* What to transmit is the number of columns in the row.
                             Compare this with the <Esc>|*-command wich expects the
                             total number of bytes in the graphic row! */
                          int count1 = count/bytes_per_column;
                          fprintf(prn_stream, "\033*%c%c%c",
                                  mode, count1 & 0xff, count1 >> 8);
                        }
                        fwrite(out_beg, 1, count, prn_stream);
                        out_beg = outl;
                        outl += n;
                   }
                while ( out_beg < out_end );

                fputc('\r', prn_stream);
                skip = bits_per_column;  /* <CR> only moves to the beginning of the row. */
           }