page%swap@Sun.COM (Bob Page) (05/09/89)
Submitted-by: allen%hpfcacn@hp-sde.sde.hp.com (Allen Norskog) Posting-number: Volume 89, Issue 118 Archive-name: util/dps.1 DPS is a program that allows you to display on the screen an image that is generated by PrintScript, which is a PostScript interpreter for the Amiga. PrintScript is a commercial program from Pixeletions. # This is a shell archive. # Remove anything above and including the cut line. # Then run the rest of the file through 'sh'. # Unpacked files will be owned by you and have default permissions. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: SHell ARchive # Run the following text through 'sh' to create: # dps.c # dps.doc # This is archive 1 of a 1-part kit. # This archive created: Mon May 8 12:14:35 1989 echo "extracting dps.c" sed 's/^X//' << \SHAR_EOF > dps.c X/* DPS V1.1 X XAuthor: Allen Norskog X XRevision history: X V1.0: 3/28/89 - (unofficial release) X V1.1: 4/23/89 - First real release X - bug fixes to V1.0 X - Allow Workbench startup X XThis program released into the Public Domain. X XThis program compiled with Manx Aztec C V3.6A using X32 bit integers. (cc +L; ln ... -lc32) */ X X#include <stdio.h> X#include <exec/memory.h> X#include <intuition/intuition.h> X#include <intuition/screens.h> X#include <graphics/display.h> X#include <graphics/gfxmacros.h> X#include <workbench/startup.h> X#include <workbench/workbench.h> X#include <workbench/icon.h> X#include <functions.h> X XFILE *fopen(),*ifile=NULL; X X X#define ARG_REQ_NUM 1 X#define ARG_INFILE 1 X X#define ERR_NUM_ARGS 1 X#define ERR_INFILE 2 X#define ERR_BAD_HEADER 3 X#define ERR_G_LIB 4 X#define ERR_INT_LIB 5 X#define ERR_P_WINDOW 6 X#define ERR_ABORT 7 X#define ERR_NO_IMAGE 8 X#define ERR_SCREEN 9 X#define ERR_S_WINDOW 10 X#define ERR_SHORT_FILE 11 X#define ERR_HEADER_VERSION 12 X#define ERR_HEADER_FLAGS 13 X X X X#define MP_S_WINDOW 0 X#define MP_QUIT 1 X X/* 8.5 * 72 = 612; 11 * 72 =792 */ X#define DEF_DOTS_WIDE 612 X#define DEF_DOTS_TALL 792 X#define DEF_HALF_DOTS_TALL 396 X X/* 612 / 16 ~= 39 */ X#define DEF_LINE_WORDS 39 X#define DEF_SMALL_LINE_WORDS 20 X#define DEF_LINE_BYTES 78 X/* For now, things are rather customized to 640 by 400 screen */ X#define DEF_SCREEN_HEIGHT 400 X#define TWO_E16 65536 X#define TWO_E16_MINUS_1 65535 X#define IMAGESIZE DEF_LINE_WORDS*DEF_DOTS_TALL X#define SMALL_IMAGESIZE DEF_SMALL_LINE_WORDS*DEF_HALF_DOTS_TALL X#define NORMALFLAGS (WINDOWSIZING|WINDOWDRAG|WINDOWCLOSE|WINDOWDEPTH) X Xextern struct WBStartup *WBenchMsg; X Xstatic char *err_msg[]= X{ X"Everything ok.\n", X"Command format: dps infile\n\n\ X Command displays a PrintScript run length encoded file.\n\n", X"Input file does not exist.\n\n", X"This is not a proper PrintScript file.\n\n", X"Graphics library won't open!\n\n", X"Intuition library won't open!\n\n", X"Unable to open page display window! Probably low on memory.\n\n", X"Dps aborted.\n\n", X"Unable to create image! Probably low on memory.\n\n", X"Unable to open custom screen! Probably low on memory.\n\n", X"Unable to open overview window! Probably low on memory.\n\n", X"File too short for even header.\n\n", X"Version number in file header must be 1.\n\n", X"Flags number in file header must be 1 (RLE).\n\n" X}; X Xint version; Xint flags; Xint xdpi; Xint ydpi; Xint width; Xint height; X Xint from_wb=FALSE; Xint bytes_per_line; Xint max_bytes_out; Xint bytes_out=0; Xint field_length; Xint field_count=0; Xint repeat_count=0; Xint data_byte=0; Xint nibble=0; Xint blank_line=TRUE; Xint new_line[DEF_LINE_BYTES]; Xint page_line_count=0; Xint screen_lines=DEF_SCREEN_HEIGHT; Xchar *con_name = "CON:20/20/600/40/ DPS V1.1"; XUSHORT *image=NULL; XUSHORT *small_image=NULL; XUSHORT color_map[]={ X0x0867, /* Gray page background to reduce flicker */ X0x0000, /* Black text on paper */ X0x0404, /* Dark purple */ X0x0640 /* Yellow */ X}; X Xstruct Image small_page = { X 0, 0, /* LeftEdge, TopEdge */ X DEF_LINE_WORDS*8, DEF_HALF_DOTS_TALL, /* Width, Height */ X 1, /* Depth */ X NULL, /* *ImageData */ X 1, 0, /* PlanePick, PlaneOnOff */ X NULL /* *NextImage */ X}; X Xstruct Image page = { X -10, 0, /* LeftEdge, TopEdge */ X DEF_LINE_WORDS*16, DEF_DOTS_TALL, /* Width, Height */ X 1, /* Depth */ X NULL, /* *ImageData */ X 1, 0, /* PlanePick, PlaneOnOff */ X NULL /* *NextImage */ X}; X Xstruct Border slide_border1 = { X 0, 0, /* LeftEdge, TopEdge */ X 1, 2, JAM1, /* FrontPen, BackPen (ignored), DrawMode */ X 0, /* Count */ X NULL, /* *XY */ X NULL /* *NextBorder */ X}; X Xstruct Border slide_border2 = { X 0, 0, /* LeftEdge, TopEdge */ X 1, 2, JAM1, /* FrontPen, BackPen (ignored), DrawMode */ X 0, /* Count */ X NULL, /* *XY */ X NULL /* *NextBorder */ X}; X Xstruct PropInfo prop_slider1 = { X FREEVERT | AUTOKNOB, /* Flags */ X 0, /* HorizPot */ X 0, /* VertPot */ X 0xFFFF, /* HorizBody */ X 0x5555, /* VertBody */ X 0, /* CWidth */ X 0, /* CHeight */ X 0, /* HPotRes */ X 0, /* VPotRes */ X 0, /* LeftBorder */ X 0 /* TopBorder */ X}; X Xstruct PropInfo prop_slider2 = { X FREEVERT | AUTOKNOB, /* Flags */ X 0, /* HorizPot */ X 0, /* VertPot */ X 0xFFFF, /* HorizBody */ X 0x5555, /* VertBody */ X 0, /* CWidth */ X 0, /* CHeight */ X 0, /* HPotRes */ X 0, /* VPotRes */ X 0, /* LeftBorder */ X 0 /* TopBorder */ X}; X Xstruct Gadget slider1 = { X NULL, /* *NextGadget */ X -18, 12, 16, -25, /* LeftEdge, TopEdge, X Width, Height */ X GADGHCOMP | GRELRIGHT | GRELHEIGHT, /* Flags */ X GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY, /* Activation */ X PROPGADGET | GZZGADGET, /* GadgetType */ X (APTR)&slide_border1, /* GadgetRender */ X NULL, /* SelectRender */ X NULL, /* *GadgetText */ X 0, /* MutualExclude */ X (APTR)&prop_slider1, /* SpecialInfo */ X 1, /* GadgetID */ X NULL /* UserData */ X}; X Xstruct Gadget slider2 = { X NULL, /* *NextGadget */ X -18, 12, 16, -25, /* LeftEdge, TopEdge, X Width, Height */ X GADGHCOMP | GRELRIGHT | GRELHEIGHT, /* Flags */ X GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY, /* Activation */ X PROPGADGET | GZZGADGET, /* GadgetType */ X (APTR)&slide_border2, /* GadgetRender */ X NULL, /* SelectRender */ X NULL, /* *GadgetText */ X 0, /* MutualExclude */ X (APTR)&prop_slider2, /* SpecialInfo */ X 1, /* GadgetID */ X NULL /* UserData */ X}; X Xstruct IntuiText req_text = { X 0,1, /* FrontPen, BackPen */ X JAM1, /* DrawMode */ X 5,4, /* LeftEdge, TopEdge */ X NULL, /* TextAttr */ X NULL, /* UBYTE *IText */ X NULL /* NextText */ X}; X Xstruct IntuiText cont_text = { X 0,1, /* FrontPen, BackPen */ X JAM1, /* DrawMode */ X 5,4, /* LeftEdge, TopEdge */ X NULL, /* TextAttr */ X (unsigned char *)"Continue",/* UBYTE *IText */ X NULL /* NextText */ X}; X Xstruct IntuiText p_menu_1_text = { X 0,1, /* FrontPen, BackPen */ X JAM1, /* DrawMode */ X 0,0, /* LeftEdge, TopEdge */ X NULL, /* TextAttr */ X (unsigned char *)"Overview",/* UBYTE *IText */ X NULL /* NextText */ X}; X Xstruct IntuiText p_menu_2_text = { X 0,1, /* FrontPen, BackPen */ X JAM1, /* DrawMode */ X 0,0, /* LeftEdge, TopEdge */ X NULL, /* TextAttr */ X (unsigned char *)"Quit", /* UBYTE *IText */ X NULL /* NextText */ X}; X Xstruct MenuItem p_menu_2 = { X NULL, /* *NextItem */ X 0,12,80,12, /* LeftEdge, TopEdge, Width, Height */ X ITEMTEXT | HIGHCOMP | ITEMENABLED, /* Flags */ X 0, /* MutualExclude */ X (APTR)&p_menu_2_text, /* ItemFill */ X 0, /* Command */ X NULL, /* *SubItem */ X 0 /* NextSelect */ X}; X Xstruct MenuItem p_menu_1 = { X &p_menu_2, /* *NextItem */ X 0,0,80,12, /* LeftEdge, TopEdge, Width, Height */ X ITEMTEXT | HIGHCOMP | ITEMENABLED, /* Flags */ X 0, /* MutualExclude */ X (APTR)&p_menu_1_text, /* ItemFill */ X 0, /* Command */ X NULL, /* *SubItem */ X 0 /* NextSelect */ X}; X Xstruct Menu project_menu = { X NULL, /* *NextMenu */ X 0,0,80,12, /* LeftEdge, TopEdge, Width, Height */ X MENUENABLED, /* Flags */ X (BYTE *)"Project", /* BYTE *MenuName */ X &p_menu_1 /* *FirstItem */ X}; X Xstatic struct NewScreen myDpsScreen = { X 0, 0, /* SHORT LeftEdge, TopEdge */ X 640, DEF_SCREEN_HEIGHT, /* Width, Height */ X 2, /* Depth */ X 0, 1, /* UBYTE DetailPen, BlockPen */ X HIRES | INTERLACE, /* USHORT ViewModes */ X CUSTOMSCREEN, /* USHORT Type */ X NULL, /* struct TextAttr *Font */ X (unsigned char *)"DPS Screen", /* UBYTE *DefaultTitle */ X NULL, /* struct Gadget *Gadgets */ X NULL /* struct BitMap *CustomBitMap */ X}; X Xstatic struct NewWindow myPageWindow = { X 0, 0, /* SHORT LeftEdge, TopEdge */ X 640, /* Width */ X DEF_SCREEN_HEIGHT, /* Height */ X -1, -1, /* UBYTE DetailPen, BlockPen */ X /* ULONG IDCMPFlags */ X CLOSEWINDOW | NEWSIZE | MENUPICK | GADGETDOWN | GADGETUP | MOUSEMOVE, X /* ULONG Flags */ X SMART_REFRESH|NOCAREREFRESH|NORMALFLAGS|GIMMEZEROZERO, X &slider1, /* struct Gadget *FirstGadget */ X NULL, /* struct Image *CheckMark */ X (unsigned char *)"DPS V1.1", /* UBYTE *Title */ X NULL, /* struct Screen *Screen */ X NULL, /* struct BitMap *BitMap */ X 80, 50, 640, 400, /* SHORT MinWidth,MinHeight, X MaxWidth, MaxHeight*/ X CUSTOMSCREEN /* USHORT Type */ X}; X Xstatic struct NewWindow mySmallWindow = { X 0, 0, /* SHORT LeftEdge, TopEdge */ X DEF_LINE_WORDS*8+28, /* Width */ X DEF_SCREEN_HEIGHT, /* Height */ X -1, -1, /* UBYTE DetailPen, BlockPen */ X /* ULONG IDCMPFlags */ X CLOSEWINDOW | NEWSIZE | MENUPICK | GADGETDOWN | GADGETUP | MOUSEMOVE, X /* ULONG Flags */ X SMART_REFRESH|NOCAREREFRESH|NORMALFLAGS|GIMMEZEROZERO, X &slider2, /* struct Gadget *FirstGadget */ X NULL, /* struct Image *CheckMark */ X (unsigned char *)"Overview", /* UBYTE *Title */ X NULL, /* struct Screen *Screen */ X NULL, /* struct BitMap *BitMap */ X 80, 50, 640, 400, /* SHORT MinWidth,MinHeight, X MaxWidth, MaxHeight*/ X CUSTOMSCREEN /* USHORT Type */ X}; X Xstruct Screen *dpsScreen=NULL; Xstruct Window *pageWindow=NULL; Xstruct Menu *pageWindowMenu=NULL; Xstruct Window *smallWindow=NULL; Xstruct RastPort *Rport1=NULL; Xstruct RastPort *Rport2=NULL; Xstruct Library *IconBase=NULL; Xstruct Library *GfxBase=NULL; Xstruct Library *IntuitionBase=NULL; X X Xvoid disp_err(x) X int x; X{ X struct FileHandle *con; X X if (from_wb) { X if (pageWindow) { X req_text.IText = (UBYTE *) err_msg[x]; X x = AutoRequest(pageWindow,&req_text,NULL,&cont_text, X NULL,NULL,600,60); X } X else { X con = Open(con_name,MODE_OLDFILE); X if (con) { X Write(con,err_msg[x],strlen(err_msg[x])); X Delay(120); X Close(con); X } X } X } X else { X printf(err_msg[x]); X } X} X Xvoid err_exit(x) X int x; X{ X disp_err(x); X exit(x); /* err_exit is not called when any windows/screens are open */ X} X Xvoid redraw_small_image() X{ X int image_lines; X int first_line; X int last_line; X X X image_lines = smallWindow->Height - smallWindow->BorderTop - X smallWindow->BorderBottom; X last_line = DEF_HALF_DOTS_TALL - image_lines; X first_line = (prop_slider2.VertPot * last_line)/ TWO_E16_MINUS_1; X X DrawImage(Rport2,&small_page,0,-first_line); X} X Xvoid redraw_image() /* redraws large image */ X{ X int image_lines; X int first_line; X int last_line; X X X image_lines = pageWindow->Height - pageWindow->BorderTop - X pageWindow->BorderBottom; X last_line = DEF_DOTS_TALL - image_lines; X first_line = (prop_slider1.VertPot * last_line)/ TWO_E16_MINUS_1; X X DrawImage(Rport1,&page,0,-first_line); X} X Xvoid redraw_small_window() /* sets slider and redraws small image */ X{ X int image_lines; X int body; X int first_line; X int last_line; X X X image_lines = smallWindow->Height - smallWindow->BorderTop - X smallWindow->BorderBottom; X body = (TWO_E16_MINUS_1 * image_lines) / DEF_HALF_DOTS_TALL; X last_line = DEF_HALF_DOTS_TALL - image_lines; X first_line = (prop_slider2.VertPot * last_line)/ TWO_E16_MINUS_1; X X DrawImage(Rport2,&small_page,0,-first_line); X ModifyProp(&slider2,smallWindow,NULL,prop_slider2.Flags, X prop_slider2.HorizPot,prop_slider2.VertPot,prop_slider2.HorizBody, X body); X RefreshGadgets(&slider2,smallWindow,NULL); X} X Xvoid redraw() /* sets slider and redraws large image */ X{ X int image_lines; X int body; X int first_line; X int last_line; X X X image_lines = pageWindow->Height - pageWindow->BorderTop - X pageWindow->BorderBottom; X body = (TWO_E16_MINUS_1 * image_lines) / DEF_DOTS_TALL; X last_line = DEF_DOTS_TALL - image_lines; X first_line = (prop_slider1.VertPot * last_line)/ TWO_E16_MINUS_1; X X DrawImage(Rport1,&page,0,-first_line); X ModifyProp(&slider1,pageWindow,NULL,prop_slider1.Flags, X prop_slider1.HorizPot,prop_slider1.VertPot,prop_slider1.HorizBody, X body); X RefreshGadgets(&slider1,pageWindow,NULL); X} X Xvoid kill_small_window() X{ X if (small_image != NULL) { X FreeMem(small_image, SMALL_IMAGESIZE*sizeof(USHORT)); X small_image = NULL; X } X if (smallWindow) { X CloseWindow(smallWindow); X smallWindow = NULL; X } X Rport2=NULL; X} X Xvoid open_small_window() X{ X int i,j,k; X int big_words; X int small_words; X X if (smallWindow == NULL) { X X small_image = (USHORT *) AllocMem(SMALL_IMAGESIZE*sizeof(USHORT), X MEMF_CHIP|MEMF_CLEAR); X if (small_image == NULL) { X disp_err(ERR_NO_IMAGE); X return; X } X small_page.ImageData = small_image; X X big_words =0; /* Offset to present row in page image */ X small_words=0; /* Offset to present row in small image */ X X /* The following loop compresses the image 2x in both X height and width */ X X for (i = 0; i<DEF_HALF_DOTS_TALL; i++) { X for (j = 0, k=0; j<DEF_SMALL_LINE_WORDS-1; j++, k += 2) { X small_image[small_words+j] = X (shrink_word(image[big_words+k])<<8) + X shrink_word(image[big_words+k+1]); X small_image[small_words+j] |= X (shrink_word(image[big_words+k+DEF_LINE_WORDS])<<8) + X shrink_word(image[big_words+k+DEF_LINE_WORDS+1]); X } X small_image[small_words+j] = (shrink_word(image[big_words+k]) X | shrink_word(image[big_words+k+DEF_LINE_WORDS])) <<8; X big_words += 2*DEF_LINE_WORDS; X small_words += DEF_SMALL_LINE_WORDS; X } X X prop_slider2.VertPot = 0; /* This is needed on second opening of X this window */ X smallWindow = OpenWindow(&mySmallWindow); X Rport2 = smallWindow->RPort; X if (smallWindow == NULL) { X kill_small_window(); X disp_err(ERR_S_WINDOW); X return; X } X redraw_small_window(); X } X} X Xvoid kill_page_window() X{ X if (image) { X FreeMem(image, IMAGESIZE*sizeof(USHORT)); X image = NULL; X } X if (pageWindow) { X if (pageWindowMenu) ClearMenuStrip(pageWindow); X pageWindowMenu = NULL; X CloseWindow(pageWindow); X pageWindow = NULL; X } X} X Xvoid kill_dps_screen() X{ X kill_small_window(); X kill_page_window(); X if (dpsScreen) { X CloseScreen(dpsScreen); X dpsScreen == NULL; X } X} X Xvoid open_page_window() X{ X myPageWindow.Screen = dpsScreen; X mySmallWindow.Screen = dpsScreen; X X pageWindow = OpenWindow(&myPageWindow); X if (pageWindow == NULL) { X kill_dps_screen(); X CloseLibrary(IntuitionBase); X CloseLibrary(GfxBase); X err_exit(ERR_P_WINDOW); X } X X pageWindowMenu = &project_menu; X SetMenuStrip(pageWindow, pageWindowMenu); X Rport1 = pageWindow->RPort; X redraw(); X} X Xvoid handle_events() X{ X int mouse_moved; X int remove_small_window; X int make_small_window; X int get_out; X struct IntuiMessage *imsg; X long class; X USHORT code; X unsigned long m1, m2, res; X short menu, item; X X m1=1L<<pageWindow->UserPort->mp_SigBit; X m2=0; X for (;;) { X res = Wait(m1|m2); X if (res & m1) { X get_out=FALSE; X mouse_moved=FALSE; X make_small_window=FALSE; X while (imsg = (struct IntuiMessage *)GetMsg(pageWindow->UserPort)) { X class = imsg->Class; X code = imsg->Code; X ReplyMsg(imsg); X switch(class) { X case CLOSEWINDOW: X get_out=TRUE; X break; X case NEWSIZE: X redraw(); X break; X case GADGETDOWN: /* Gadget stuff all the same */ X case GADGETUP: X case MOUSEMOVE: X mouse_moved = TRUE; X break; X case MENUPICK: X menu = MENUNUM(code); X item = ITEMNUM(code); X if (menu == 0) { X switch(item) { X case(MP_S_WINDOW): X make_small_window=TRUE; X break; X case(MP_QUIT): X get_out=TRUE; X break; X default: X break; X } X } X break; X default: X break; X } X } X if (get_out) return; X if (mouse_moved) redraw_image(); X if (make_small_window) { X open_small_window(); X if (smallWindow) m2=1L<<smallWindow->UserPort->mp_SigBit; X } X } X if (res & m2) { X mouse_moved = FALSE; X remove_small_window = FALSE; X while (imsg = (struct IntuiMessage *)GetMsg(smallWindow->UserPort)) { X class = imsg->Class; X code = imsg->Code; X ReplyMsg(imsg); X switch(class) { X case CLOSEWINDOW: X remove_small_window = TRUE; X break; X case NEWSIZE: X redraw_small_window(); X break; X case GADGETDOWN: /* Gadget stuff all the same */ X case GADGETUP: X case MOUSEMOVE: X mouse_moved = TRUE; X break; X default: X break; X } X } X if (remove_small_window) { X kill_small_window(); X m2 = 0; X } X else if (mouse_moved) redraw_small_image(); X } X } X} X Xint shrink_byte(c) /* Compress a byte into a nibble. X This routine not used at present, X but might be useful */ X int c; X{ X int nibble; X X nibble = 0; X if (c & 3) nibble = 1; X if (c & 12) nibble |= 2; X if (c & 48) nibble |= 4; X if (c & 192) nibble |= 8; X return(nibble); X} X Xint shrink_word(c) /* Compress a 16 bit word into 8 bits */ X unsigned int c; X{ X unsigned int byte; X X byte = 0; X if (c & 0x3) byte = 1; X if (c & 0xc) byte |= 2; X if (c & 0x30) byte |= 4; X if (c & 0xc0) byte |= 8; X if (c & 0x300) byte |= 0x10; X if (c & 0xc00) byte |= 0x20; X if (c & 0x3000) byte |= 0x40; X if (c & 0xc000) byte |= 0x80; X return(byte); X} X Xvoid clear_new_line() X{ X int j; X X for (j = 0; j<DEF_LINE_BYTES; j++) { X new_line[j] = 0; X } X} X Xint flip_byte(c) /* Reverses the bit order */ X int c; X{ X int b; X X b = ((c & 1) <<7) | ((c & 2) <<5) | ((c & 4) <<3) | ((c & 8) <<1); X b |= ((c & 0x80) >>7) | ((c & 0x40) >>5) | ((c & 0x20) >>3) | X ((c & 0x10) >>1); X return(b); X} X Xvoid clear_image() /* Sets up large image. Draws a (8.5 x 11) page X border into the image. */ X{ X int i; X int j; X X image = (USHORT *) AllocMem(IMAGESIZE*sizeof(USHORT), X MEMF_CHIP|MEMF_CLEAR); X if (image == NULL) { X err_exit(ERR_NO_IMAGE); X } X page.ImageData = image; X X /* Draw a page border */ X i = (DEF_DOTS_TALL-1) * DEF_LINE_WORDS; /* point to last line */ X for (j = 1; j<DEF_LINE_WORDS; j++) { X image[j] = 0xFFFF; X image[i+j] = 0xFFFF; X } X image[0] = 0x000F; /* 8.5inches * 72dpi = 612 bits X = 38.25 (16bit words) X Therefore, we need 39 words. X Since the line is flipped, data starts on the X third nibble */ X image[i] = 0x000F; X for (j = 1, i=DEF_LINE_WORDS; X j<DEF_DOTS_TALL-1; j++, i += DEF_LINE_WORDS) { X X image[i] = 0x0008; /* Beginning of line */ X image[i+DEF_LINE_WORDS-1] = 0x0001; /* End of line */ X } X} X Xvoid enter_new_line() /* puts a line into the large image */ X{ X int b; X int i; X int j; X int k; X X page_line_count++; X if (page_line_count > DEF_DOTS_TALL) return; X if (blank_line != TRUE) { X k = (DEF_DOTS_TALL-page_line_count)*DEF_LINE_WORDS; X for (b=j= 0; j<DEF_LINE_WORDS; j++, b += 2) { X i = (new_line[b]<<8) + new_line[b+1]; X image[k+j] ^= i; /* XOR so that writes on page edges are X visible */ X } X } X blank_line = TRUE; X} X Xvoid read_header() /* Reads the header of a PrintScript run-length-encoded X file. */ X{ X int c; X int i; X int done; X X X /* Read header and check if ok */ X done = FALSE; X i=0; X while (done != TRUE) { X c = getc(ifile); X if (c == EOF) { X done = TRUE; X disp_err(ERR_SHORT_FILE); X err_exit(ERR_BAD_HEADER); X } X else { X i++; X switch (i) { X case 1: X version = c*256; X break; X case 2: X version += c; X /* This needs to be re-thought if future versions X come along. */ X if (version != 1) { X disp_err(ERR_HEADER_VERSION); X err_exit(ERR_BAD_HEADER); X } X break; X case 3: X flags = c*256; X break; X case 4: X flags += c; X if (flags != 1) { X disp_err(ERR_HEADER_FLAGS); X err_exit(ERR_BAD_HEADER); X } X break; X case 5: X xdpi = c*256; X break; X case 6: X xdpi += c; X break; X case 7: X ydpi = c*256; X break; X case 8: X ydpi += c; X break; X case 9: X width = c*256; X break; X case 10: X width += c; X break; X case 11: X height = c*256; X break; X case 12: X height += c; X done = TRUE; X break; X default: X err_exit(ERR_BAD_HEADER); /* Should never get here */ X break; X } X } X } X X} X Xvoid build_image() /* This reads the part of the PrintScript X run-length-encoded file and builds the image. X Since the PrintScript image is "upside-down", X we need to put the top line to the bottom, etc., X and also reverse each line left-to-right. */ X{ X int c; X int i; X int j; X int done; X X clear_new_line(); X blank_line = TRUE; X done = FALSE; X i=0; X while (done != TRUE) { X c = getc(ifile); X if (c == EOF) { X done = TRUE; X } X else { X i++; X switch (i) { X case 1: X field_length = c*256; X field_count = 0; X bytes_out = 0; X break; X case 2: X field_length += c; X if (field_length == 0) { X i = 0; X enter_new_line(); /* enter a blank line */ X /* clear_new_line(); */ X } X else blank_line = FALSE; X break; X case 3: X repeat_count = c + 1; X field_count++; X break; X case 4: X i = 2; X data_byte = flip_byte(c); /* Reverse byte left-to-right */ X field_count++; X if ((repeat_count + bytes_out) > max_bytes_out) { X repeat_count = max_bytes_out - bytes_out; X } X for (j = 0; j<repeat_count; j++) { X /* Put bytes in "backwards". We want the first X byte to go way over to the right in X new_line[77]. */ X bytes_out++; X new_line[DEF_LINE_BYTES-bytes_out] = data_byte; X } X if (field_count >= field_length) { X i = 0; X enter_new_line(); X clear_new_line(); X } X break; X default: X err_exit(ERR_BAD_HEADER); /* Should never get here */ X break; X } X } X } X X} X Xvoid get_wb_args(wb_msg) X struct WBStartup *wb_msg; X{ X struct WBArg *wb_arg; X struct DiskObject *diskobj; X char **toolarray; X int i; X char *s; X X wb_arg = wb_msg->sm_ArgList; X if ((IconBase = OpenLibrary("icon.library",0))) { X diskobj = (struct DiskObject *) GetDiskObject(wb_arg->wa_Name); X if (diskobj) { X toolarray = (char **) diskobj->do_ToolTypes; X s = (char *) FindToolType(toolarray,"FILE"); X if (s) { X ifile=fopen(s,"r"); X } X FreeDiskObject(diskobj); X } X CloseLibrary(IconBase); X } X if (!ifile) { X err_exit(ERR_INFILE); X } X} X Xmain(argc,argv) X int argc; X char *argv[]; X{ X struct ViewPort *vp; X X from_wb = (argc == 0); X X if (from_wb) { X get_wb_args(WBenchMsg); X } X else { X if (argc <= ARG_REQ_NUM) { X err_exit(ERR_NUM_ARGS); X } X ifile=fopen(argv[ARG_INFILE],"r"); X if (!ifile) { X err_exit(ERR_INFILE); X } X } X X max_bytes_out = DEF_LINE_BYTES; X X read_header(); X X /* Old debug stuff X printf("version = %d\n", version); X printf("flags = %d\n", flags); X printf("xdpi = %d\n", xdpi); X printf("ydpi = %d\n", ydpi); X printf("width = %d\n", width); X printf("height = %d\n", height); X printf("max_bytes_out = %d\n", max_bytes_out); X */ X X clear_image(); X build_image(); X close(ifile); X X /* If we haven't aborted by this point, start doing graphics */ X X GfxBase = OpenLibrary("graphics.library", 0L); X if (GfxBase == NULL) { X if (image != NULL) { X FreeMem(image, IMAGESIZE*sizeof(USHORT)); X image = NULL; X } X err_exit(ERR_G_LIB); X } X IntuitionBase = OpenLibrary("intuition.library", 0L); X if (IntuitionBase == NULL) { X if (image != NULL) { X FreeMem(image, IMAGESIZE*sizeof(USHORT)); X image = NULL; X } X CloseLibrary(GfxBase); X err_exit(ERR_INT_LIB); X } X X dpsScreen = OpenScreen(&myDpsScreen); X if (dpsScreen == NULL) { X kill_dps_screen(); X CloseLibrary(IntuitionBase); X CloseLibrary(GfxBase); X err_exit(ERR_SCREEN); X } X vp = &dpsScreen->ViewPort; X LoadRGB4(vp,color_map,4); X X open_page_window(); X handle_events(); X X kill_dps_screen(); X if (IntuitionBase) CloseLibrary(IntuitionBase); X if (GfxBase) CloseLibrary(GfxBase); X return(0); X} X X X_abort() X{ X kill_dps_screen(); X if (IntuitionBase) CloseLibrary(IntuitionBase); X if (GfxBase) CloseLibrary(GfxBase); X exit(ERR_ABORT); X} X X SHAR_EOF echo "extracting dps.doc" sed 's/^X//' << \SHAR_EOF > dps.doc X DPS X Version 1.1 X X Author: Allen Norskog X April 23, 1989 X X XPUBLIC DOMAIN NOTICE X XThis program is placed in Public Domain. It may be freely copied. XI developed this program to suit my own needs. I hope it will be Xuseful to others. The source is included so that you can make Xmodifications to suit your own needs. I would appreciate any comments Xor bug reports. X X XDESCRIPTION X XDPS is designed to work with the PrintScript program by Pixelations Xto provide a page previewer. PrintScript is a PostScript interpreter. X XPresently, PrintScript does not include a screen previewer. This Xprogram addresses this shortcoming. PrintScript does have the ability Xto write a "bitmap" picture to a file. This program reads in such Xa file and displays the "page" on the screen. X XThe main motivation behind DPS, was to have a tool that would show Xone's mistakes, such as printing off the page, or not getting things Xcentered. For this, one would like something quick. Generating Xa file for DPS is not really quick, but can be two to three times Xfaster than actually printing. X XDPS uses a lower resolution picture than what you will probably Xfinally print. The advantage here is that the smaller picture takes Xless time to compute. Also, the picture file takes less disk or Xmemory space than if you generated a hi-res image file. X XPresently, DPS is set to display one fixed page size -- 8.5 by 11 inches. XHow it appears on the screen is dependent of course on your monitor. XWith a standard Amiga monitor, it will actually be a bit larger. Also Xthe image will be slightly tall - you will notice this a bit, for Xexample, when drawing a circle. X XOriginally, what I thought I wanted was a full page overview, like that Xin the "Overview" window. Since I couldn't get PrintScript to generate Xless than 72 dpi, I had approximately twice as many dots (pixels) in each Xdirection than what I originally wanted. Having the dots available Xanyway, I did the larger main window, and have generally liked it Xbetter. One can see the details much more clearly in the main window. XThe Overview window is compressed 2X in both directions compared to the Xmain window. Each pixel in the Overview image represents 2x2 pixels Xin the main window. If any of the pixels in the 2x2 square is black, Xthe corresponding pixel in the Overview window will be black. This Xmakes sure that (normal black) lines don't disappear -- if you are Xgoing to be printing something in that area, you will see something Xon the screen. However, gray areas get darker (or totally black) Xon the Overview window. X X X XCONFIGURING PRINTSCRIPT X XDPS uses the file output feature of PrintScript. This file describes Xthe image in a run-length-encoded manner documented in the PrintScript Xmanual. For DPS to work properly, you need to specify that you are Xgoing to use an 8.5 by 11 inch page, with no margins, and at 72 dots Xper inch. X XYou need to run the configuration program on the PrintScript disk to Xcreate a configuration file (Config.ps) that tells PrintScript to write Xto a file. See the manual for information. Below is a sample session: X X1> configure X XScreen frequency (10-360)? 10 (You may choose from 10 to 72) XScreen angle (0-90)? 45 (You may choose 0 to 90) XAre you using a preferences printer (Y or N)? N XWidth of printable page in inches (1.0 - 14.0)? 8.5 XHeight of printable page inches (1.0 - 14.0)? 11 XHorizontal dots per inch (72-360)? 72 XVertical dots per inch (72-360)? 72 XPrinter port name or filename (par:, ser: or file)? ram:dps_file XName of printer driver? File XUnprintable left margin in inches (0.0 - 1.0)? 0.0 XUnprintable bottom margin in inches (0.0 - 1.0)? 0.0 X XYou may choose a file name other than ram:dps_file. Just remember Xwhat you called it so you know where to find it. The file generated Xwill generally not be too large because of the low resolution Xand the compression used. Thus, you should be able to usually write it Xto ram: to speed things up. X XThe first two questions in the configuration example shown above Xrelate to settings for half-tone images. You may want to experiment Xwith values here. See the PrintScript manual or a PostScript manual Xfor more info. X XAfter you run PrintScript on your PostScript file, the output file Xshould be available to use in DPS. X X XRUNNING DPS X XDPS can be run from either the CLI (like PrintScript), or from the XWorkbench. X XFrom the CLI: X X You simply type dps followed by the file name. If you ran the X configuration as described above, you would enter at the cli prompt: X X 1> dps ram:dps_file X X XFrom the Workbench: X X The file that DPS will be looking for is given in the ToolTypes for X the DPS icon (info file). Find the DPS icon. Click on it once. X Select the Workbench-Info menu item from the Workbench screen. X Change the ToolTypes line, so "FILE" is pointed to the file you X want. For example, if you used the above configuration, you would X set the line to be: X X FILE=ram:dps_file X X Save the changes you made to the info file. Now the DPS icon is X ready for use. Double click on the icon to run DPS. X X XWhen the DPS program is first loaded, it checks if the file specified Xis really a PrintScript file. If the file is okay, it will build an Ximage for display. DPS will open a custom interlace screen. A gray Xpage was chosen to reduce flicker. The writing on the page will be Xblack. A page outline is displayed, so you can see where the "edges" Xwill be. If you write to the edge, that area of the edge will be Xreversed, so you can tell that you are attempting to write there. XYou are probably too close for what your printer will do. X XA slider along the right allows you to scroll up and down the page. X XYou can exit DPS by hitting the "close button" in the DPS window, or Xuse the "Quit" menu option. X XAnother menu item is labeled "Overview". Selecting this will bring Xup what was intended to be a full page view on the screen. Actually, Xit is a couple lines short, so a slider bar is also provided in the XOverview window as well. The image in the Overview window is half Xas wide and half as tall as the image in the main DPS window. Closing Xthe Overview window returns you to the main DPS window. X X XERRORS X XThe file you specify will be checked to see if it is a PrintScript Xtype file. If the beginning of the file is not set up like it expects X(see the header definition in the PrintScript manual), it will assume Xthat you are trying to read a non-PrintScript file. DPS will display Xa message describing the problem and the program will exit. Actually XDPS will only require that the "version" be 1 and that "flags" be 1. XAll the other fields are ignored for now, so it is important that you Xuse the setup described above. X XIf DPS is started from the CLI, any error messages will be displayed Xin your CLI window. Thus, you can have a log of any error messages. XIf the program is started from the Workbench, error messages may Xbe displayed in requestors, or a text window that displays briefly. X X XMISCELLANEOUS X XTo let you try the DPS program, an example file (dps.circle) is Xincluded. This file was generate with PrintScript using an adaptation Xof one of the example programs in the Adobe "PostScript Language XTutorial and Cookbook". To try it type at the the CLI prompt: X X1> dps dps.circle X XOR double click on the dps icon. The icon has the ToolType set for X"FILE=dps.circle", so that the demo can be readily seen. Change Xthe Tool Type entry as described above for actual use. X X XAllen Norskog X900 Whaler's Way XFort Collins, CO 80525 X X-------------------------- XTrademark acknowledgements X XPrintScript is a trademark of Pixelations XPostScript is a trademark of Adobe Systems, Inc. SHAR_EOF echo "End of archive 1 (of 1)" # if you want to concatenate archives, remove anything after this line exit