/*
 * Transfer routine for HP_Deskjet_670C
 */

#include <exec/types.h>
#include <devices/prtgfx.h>
#include <devices/prtbase.h>
#include <devices/printer.h>

#define NUMCOLORCMD 7

/* Prototype */
void Transfer(struct PrtInfo *p, UWORD y, UBYTE *colors[], UWORD RowSize, UWORD NumColorBufs);

void Transfer(struct PrtInfo *PInfo, UWORD y, UBYTE *colors[], UWORD RowSize, UWORD NumColorBufs)
{
        extern struct PrinterData *PD;
        extern struct PrinterExtendedData *PED;

        static UBYTE bit_table[] = {128, 64, 32, 16, 8, 4, 2, 1};
        UBYTE *dmatrix, Black, dvalue, threshold;
        union colorEntry *ColorInt;
        UWORD x, width, sx, *sxptr;
        UBYTE Yellow, Magenta, Cyan, *bptr, *yptr, *mptr, *cptr;

        /* pre-compute */
        /* printer non-specific, MUST DO FOR EVERY PRINTER */
        x = PInfo->pi_xpos; /* get starting x position */
        ColorInt = PInfo->pi_ColorInt; /* get ptr to color intensities */
        sxptr = PInfo->pi_ScaleX;
        width = PInfo->pi_width; /* get # of source pixels */
        bptr = colors[0];           
        cptr = colors[1];
        mptr = colors[2];
        yptr = colors[3];

        /* pre-compute threshold; are we thresholding? */

        if (threshold = PInfo->pi_threshold) { /* thresholding */
                dvalue = threshold ^ 15; /* yes, so pre-compute dither value */
                do { /* for all source pixels */
                        /* pre-compute intensity value for Black */
                        Black = ColorInt->colorByte[PCMBLACK];
                        ColorInt++; /* bump ptr for next time */

                        sx = *sxptr++;

                        /* dither and render pixel */
                        do { /* use this pixel 'sx' times */
                                /* if we should render Black */
                                if (Black > dvalue) {
                                        /* set bit */
                                        *(bptr + (x >> 3)) |= bit_table[x & 7];
                                }
                                ++x; /* done 1 more printer pixel */
                        } while (--sx);
                } while (--width);
        }
        else { /* not thresholding, pre-compute ptr to dither matrix */
             dmatrix = PInfo->pi_dmatrix + ((y & 3) << 2);
             if (PD->pd_Preferences.PrintShade == SHADE_GREYSCALE)
             {
                do { /* for all source pixels */
                        /* pre-compute intensity value for Black */
                        Black = ColorInt->colorByte[PCMBLACK];
                        ColorInt++; /* bump ptr for next time */

                        sx = *sxptr++;

                        /* dither and render pixel */
                        do { /* use this pixel 'sx' times */
                                /* if we should render Black */
                                if (Black > dmatrix[x & 3]) {
                                        /* set bit */
                                        *(bptr + (x >> 3)) |= bit_table[x & 7];
                                }
                                ++x; /* done 1 more printer pixel */
                        } while (--sx);
                } while (--width);
             }
             else
             { /* color */
               do {
                    Black = ColorInt->colorByte[PCMBLACK];
                    Yellow = ColorInt->colorByte[PCMYELLOW];
                    Magenta = ColorInt->colorByte[PCMMAGENTA];
                    Cyan = ColorInt->colorByte[PCMCYAN];
                    ColorInt++;

                    sx = *sxptr++;

                    do {
                         dvalue = dmatrix[x & 3];
                         if (Black > dvalue)
                              *(bptr + (x >> 3)) |= bit_table[x & 7];
                         else
                         {
                              if (Yellow > dvalue)
                                   *(yptr + (x >> 3)) |= bit_table[x & 7];
                              if (Magenta > dvalue)
                                   *(mptr + (x >> 3)) |= bit_table[x & 7];
      	                     if (Cyan > dvalue)
   	                           *(cptr + (x >> 3)) |= bit_table[x & 7];
                         }
                        ++x;
                    } while (--sx);
               } while (--width);
             } /* endif */
         } /* endif */
} /* end main */
