home *** CD-ROM | disk | FTP | other *** search
- (c) Copyright 1989-1999 Amiga, Inc. All rights reserved.
- The information contained herein is subject to change without notice, and
- is provided "as is" without warranty of any kind, either expressed or implied.
- The entire risk as to the use of this information is assumed by the user.
-
-
-
- Programmer Notes on Calling the V1.3 Printer Device
- ---------------------------------------------------
-
- by David Berezowski
-
- The printer device has been exetensively revised under V1.3 of the Amiga
- system software. The following programmer's notes are presented to help
- you take full advantage of those changes in your application software.
- These notes assume that you are already familiar with how the printer
- device works - for more information, see the ROM Kernel manual.
-
-
- Arguments to DumpRPort
- ----------------------
-
- io_Command PRD_DUMPRPORT.
- io_RastPort pointer to a RastPort - could be in fastmem.
- io_ColorMap pointer to a ColorMap - could be your own custom one.
- io_Modes the 'modes' flag from a ViewPort structure (you can fake
- it but the upper word is reserved and should be zero).
- io_SrcX x offset into the RastPort to start printing from.
- io_SrcY y offset into the RastPort to start printing from.
- io_SrcWidth width of the RastPort to print from io_SrcX.
- io_SrcHeight height of the RastPort to print from io_SrcY.
- io_DestCols width of the printout in printer pixels.
- io_DestRows height of the printout in printer pixels.
- io_Special flag bits - these are explained below.
-
-
-
- The Old Special Flags
- ---------------------
-
- SPECIAL_MILROWS and SPECIAL_MILCOLS - the associated parameter is specified
- in thousandths of an inch on the printer; ie. if DestCols = 8000, and
- DestRows = 10500 then the printout would be 8.000 x 10.500 inches.
-
- SPECIAL_FULLROWS and SPECIAL_FULLCOLS - the specific dimension is set to the
- maximum possible as determined by the printer limits or the configuration
- limits, whichever is less.
-
- SPECIAL_FRACROWS and SPECIAL_FRACCOLS - the associated parameter is taken
- to be a longword binary fraction of the maximum for that dimension; ie. if
- SPECIAL_FRACCOLS is set and DestCols = 0x8000 then the width of the dumped
- picture would be 1/2 (0x8000 / 0xffff) the width of the paper.
-
- SPECIAL_CENTER - the image will be automatically centered.
-
- SPECIAL_ASPECT - one of the dimensions may be reduced or expanded to
- preserve the aspect-ratio of the print.
-
- SPECIAL_DENSITY (1-4) - see SPECIAL_DENSITY under the new flags section below.
-
- SPECIAL_TRUSTME - the printer specific driver is instructed to not issue a
- reset command before and after the dump. If this flag is NOT checked by the
- printer specific driver then setting this flag has no effect. Since we now
- recommend that printer driver writers no longer issue a reset command (ever)
- it is probably a good idea to always set this flag when calling for a dump.
-
-
- The New Special Flags
- ---------------------
-
- SPECIAL_DENSITY1 to SPECIAL_DENSITY7 - These were originally designed to allow
- a program to specify up to 7 print densities. However, these flags are now
- obselete as they are overridden by the density setting in Preferences. If you
- want to change the density, refer to the section on changing the printer
- device's copy of Preferences. The actual density in use can be determined by
- a program using the SPECIAL_NOPRINT flag described below.
-
- SPECIAL_NOFORMFEED - Allows for the mixing of text and graphics or multiple
- graphic dumps on page oriented printers (usually laser jet printers). When
- this flag is set the page will not be ejected after a graphic dump. If you
- perform another graphic dump without this flag set OR close the printer device
- after printing text after a graphic dump, the page will be ejected. This
- flag MUST be set if you are doing strip printing (covered later on in this
- article).
-
- SPECIAL_NOPRINT - Performs internal calculations, doesn't print and exits.
- This gives the calling program a chance to see what the printer specific
- values are for any given density. This is useful for determine the dot
- density and the maximum dots the printer has for any given density.
-
- This option also computes the final print size, and sets 'io_DestCols' and
- 'io_DestRows' in the calling program's 'IODRPReq' structure. This allows
- the calling program to see what the final print size would be in printer
- pixels. Note that it modifies the 'io_DestCols' and 'io_DestRows' fields of
- your 'IODRPReq' structure.
-
-
-
- Data Structures
- ---------------
-
- The printer data structures can be read once you have opened the printer
- device. Below is a code fragment to show how to do this.
-
- #include <exec/types.h>
- #include <devices/printer.h>
- #include <devices/prtbase.h>
-
- struct IODRPReq PReq;
- struct PrinterData *PD;
- struct PrinterExtendedData *PED;
-
- /* open the printer device if it opened... */
- if (OpenDevice("printer.device", 0, &PReq, 0) == NULL) {
-
- /* get pointer to printer data */
- PD = (struct PrinterData *)PReq.io_Device;
-
- /* get pointer to printer extended data */
- PED = &PD->pd_SegmentData->ps_PED;
-
- /* let's see what's there */
- printf("PrinterName = '%s', Version=%u, Revision=%u",
- PED->ped_PrinterName, PD->pd_SegmentData->ps_Version,
- PD->pd_SegmentData->ps_Revision,);
-
- printf("PrinterClass=%u, ColorClass=%u",
- PED->ped_PrinterClass, PED->ped_ColorClass);
-
- printf("MaxColumns=%u, NumCharSets=%u, NumRows=%u",
- PED->ped_MaxColumns, PED->ped_NumCharSets,
- PED->ped_NumRows);
-
- printf("MaxXDots=%lu, MaxYDots=%lu, XDotsInch=%u,YDotsInch=%u",
- PED->ped_MaxXDots, PED->ped_MaxYDots,
- PED->ped_XDotsInch, PED->ped_YDotsInch);
-
- CloseDevice(&PReq); /* close the printer device */
- }
-
- If you want the user to be able to access printer preferences without actually
- having to run Preferences (like DPAINT II's printer requester does), then use
- the code fragment above to examine the current settings. This can be done by
- refering to 'PD->pd_Preferences'. Note that the printer device must already
- be opened at this point.
-
- Next, put up a requester and allow the user to change whatever parameters
- they choose. Remember, you are responsible for range checking these
- selections. Listed below are the printer preferences items and their valid
- ranges.
-
-
- Text Preferences
- ----------------
- PrintPitch - PICA, ELITE, FINE.
- PrintQuality - DRAFT, LETTER.
- PrintSpacing - SIX_LPI, EIGHT_LPI.
- PrintLeftMargin - 1 to PrintRightMargin.
- PrintRightMargin - PrintLeftMargin to 999.
- PaperLength - 1 to 999.
-
- Graphic Preferences
- -------------------
- PrintImage - IMAGE_POSITIVE, IMAGE_NEGATIVE.
- PrintAspect - ASPECT_HORIZ, ASPECT_VERT.
- PrintShade - SHADE_BW, SHADE_GREYSCALE, SHADE_COLOR.
- PrintThreshold - 1 to 15.
- PrintFlags - CORRECT_RED, CORRECT_GREEN, CORRECT_BLUE, CENTER_IMAGE,
- IGNORE_DIMENSIONS, BOUNDED_DIMENSIONS, ABSOLUTE_DIMENSIONS,
- PIXEL_DIMENSIONS, MULTIPLY_DIMENSIONS, INTEGER_SCALING,
- ORDERED_DITHERING, HALFTONE_DITHERING, FLOYD_DITHERING,
- ANTI_ALIAS, GREY_SCALE2.
- PrintMaxWidth - 0 to 65535.
- PrintMaxHeight - 0 to 65535.
- PrintDensity - 1 to 7.
- PrintXOffset - 0 to 255.
-
-
- Asynchronous IO
- ---------------
-
- We recommend that you use asynchronous IO for printing in your programs and
- give the user a way of aborting all requests. Here are the notes on the
- recommended way to do this.
-
- To send requests for IO:
-
- struct IORequest *ioreq;
- struct MsgPort *port;
- UBYTE signal;
-
- port = ioreq->io_Message.mn_ReplyPort;
- signal = port->mp_SigBit;
-
- SendIO(ioreq); /* send request */
- Wait(signal); /* wait for completion (go to sleep) */
- while ((Msg = GetMsg(port)) != NULL) { /* get ALL messages */
- }
-
-
- To abort a previous request for IO use:
-
- struct IORequest *ioreq;
-
- AbortIO(ioreq); /* abort request */
- WaitIO(ioreq); /* wait for reply */
- /* at this point you can re-use 'ioreq'. */
-
-
- In the code fragments above 'ioreq' could be any one of:
-
- a) struct IOStdReq /* a standard i/o request */
- b) struct IODRPReq /* a dumprport i/i request */
- c) struct IOPrtCmdReq /* a printer command i/o request */
-
-
- Strip Printing
- --------------
-
- Strip printing is a technique which allows you to print a picture that
- normally requires lots of memory when you only have a little to spare.
- This trick works by creating a temporary rastport as wide as your source
- rastport but not as high. You then render a horizontal strip of your source
- rastport into the temporary rastport and dump it, moving down your rastport
- for each dump.
-
- The height of the strip must be an integer multiple of the printer's NumRows
- if you are doing a non-aspect-ratio-corrected picture. You can find NumRows
- by checking PED->ped_NumRows with the code fragment shown above.
-
- If you are doing an aspect-ratio-corrected picture then you'll have to use
- the SPECIAL_NOPRINT flag to find a DestRows that is an integer multiple of
- NumRows. You do this by varying your source height and asking for a
- SPECIAL_NOPRINT dump until DestRows comes back with a number that is an
- integer multiple of NumRows.
-
- Another consideration to keep in mind is that DestRows should also be
- evenly divisible by 4 since the printer device uses a 4x4 dither matrix.
- You only need to worry about this if you are doing a grey-scale or color
- dump as b&w dumps do not do any dithering. Fortunately most printers have
- a NumRows that is evenly divisible by 4.
-
- If you are going to do strip printing and you want SMOOTHING to work across
- strip boundaries, you must add a raster line above and below the actual area
- that you are printing. The line above should be the last line from the
- previous strip. The line below should be the first line from the next strip.
- Don't forget to omit the line above on the first strip, and the line below
- on the last strip.
-
- So if your source data is 200 lines high and you are printing in strips of
- 50 lines (ie. 4 separate dumps), your strip rastport will need to be 52
- lines high. Below is one scenario for doing the dump:
-
- 1st strip - copy source line 0 thru 50 (51 lines) to strip rastport
- lines 0 thru 50 (51 lines).
-
- - io_SrcY = 0, io_Height = 50.
-
- - here the printer device can see that there is no line
- above the first line to dump (since SrcY = 0) and that
- there is a line below the last line to dump (since we
- have a 52 line rastport and are only dumping 51 lines).
-
-
- 2nd strip - copy source line 49 thru 100 (52 lines) to strip rastport
- lines 0 thru 51 (52 lines).
-
- - io_SrcY = 1, io_Height = 50.
-
- - here the printer device can see that there is a line
- above the first line to dump (since SrcY = 1) and that
- there is a line below the last line to dump (since we have
- a 52 line rastport and are only dumping 50 lines).
-
- 3rd strip - copy source line 99 thru 150 (52 lines) to strip rastport
- lines 0 thru 51 (52 lines).
-
- - io_SrcY = 1, io_Height = 50.
-
- - here the printer device can see that there is a line
- above the first line to dump (since SrcY = 1) and that
- there is a line below the last line to dump (since we
- have a 52 line rastport and are only dumping 50 lines).
-
- 4th strip - copy source line 149 thru 199 (51 lines) to strip rastport
- lines 1 thru 51 (51 lines).
-
- - io_SrcY = 2, io_Height = 50.
-
- - here the printer device can see that there is a line
- above the first line to dump (since SrcY = 2) and that
- there is no line below the last line to dump (since we
- have a 52 line rastport and are dumping only 50 lines).
-
-
- Error Codes
- -----------
-
- If an error comes back to you please try and relay this back to the user
- instead of simply not printing. Current errors and descriptions are:
-
- PDERR_NOERR /* clean exit, no errors */
- PDERR_CANCEL /* user canceled print */
- PDERR_NOTGRAPHICS /* printer cannot output graphics */
- PDERR_INVERTHAM /* OBSOLETE */
- PDERR_BADDIMENSION /* print dimensions illegal */
- PDERR_DIMENSIONOVFLOW /* OBSOLETE */
- PDERR_INTERNALMEMORY /* no memory for internal variables */
- PDERR_BUFFERMEMORY /* no memory for print buffer */
-
-
- 12 Bit Planes
- -------------
-
- The V1.3 printer device can dump up to 12 bit planes of data from either
- chip or fast memory; use this to your advantage. Assume we are using a
- package called YAD (Yet Another Digitizer) that captures data as 24-bit RGB
- files and displays them on the Amiga in HAM mode. When YAD goes to print
- it simply does a screen dump of the HAM image.
-
- Well we all know that the HAM image is only an approximation of the real
- colors. Wouldn't it be nice if YAD had an option whereby it would build
- a 12-bit plane image in fastmem and dump that to the printer. This would
- produce much better looking output as each pixel could be any 1 of 4096
- colors - with none of the HAM limitations!
-
-
- Large Bit Maps
- --------------
-
- Another new feature you can exploit is the ability of the V1.3 printer
- device to dump very large bitmaps from either chip or fast memory.
- Suppose we have an application called YART (Yet Another Ray Tracer) that
- ray traces images to the screen in 320x400 resolution. When YART goes to
- print it simply does a screen dump of the low res 320x400 screen. We
- could expand the printed image to a size of 1280x1600 but then each single
- screen pixel is expanded to a (rather chunky) 4x4 block of printer pixels.
-
- Wouldn't it be nice if YART had an option that would allow us to create a
- 1280x1600 image in fastmem or on disk and then dump that. This would
- produce a very impressive picture as 1 source pixel would correspond to 1
- printer pixel (ie. no jaggies)!
-
-
- Aspect Ratio
- ------------
-
- When dumping a non-displayed rastport you have two choices for aspect-ratio
- correction. You can either do it yourself or let the printer device do it
- for you.
-
- Doing it Yourself
-
- a) You must look at the printer's XDotsInch and YDotsInch and
- account for the fact that the printer may not have square
- pixels. You can then ask for a non-aspect-ratio-corrected
- dump; probably a 1:1 dump.
-
- Letting the Printer Device Do It
-
- a) You could build your rastport such that the dimensions are an
- integer multiple of one the Amiga's normal display resolutions
- and then set the io_Modes argument to an appropriate value.
-
- For example, if your rasport dimensions were 1280 x 800 (an even
- multiple of 640 x 400) you would want to set io_Modes to
- 'LACE | HIRES'. Now the normal aspect-ratio correction code
- of the printer device will work correctly (if you turn it on).
-
- b) You could build an arbitrary sized rastport and set
- GfxBase->NormalDPMX and GfxBaseNormalDPYM to the dimensions
- of your rastport. You would then ask for a aspect-ratio-corrected
- dump and the printer device will figure it all out. If you use
- this option you must restore GfxBase->NormalDPMX and
- GfxBaseNormalDPYM to their previous values after the dump.
-
- I know that math scholars among you are probably saying,
- 'Hey, if I have a square rastport, can't I just set DPMX and DPMY
- both to 1?'. Mathematically this is correct BUT for mysterious
- reasons DPMX and DPMY must always be >= 182. So if you have a
- a square rastport you can set DPMX and DPMY to 182.
-
-
- 12 Bit Planes and Large Bit Maps
- --------------------------------
-
- Obviously the above two techniques require that the system have quite
- a bit of memory floating around; but they do have their uses. Large bit maps
- can be utilized by paint, desktop publishing, CAD and ray tracing programs
- to produce printed output to the resolution of the output device. Remember
- that the printer's resolution can be determined programatically by looking at
- the PED structure discussed earlier. Twelve bit plane rastports can be used
- to produce printed output which exceeds the Amiga's HAM display limitation.
- Combining these two techniques can give amazingly good printed output.
-
-
- Miscellaneous Items
- -------------------
-
- There are two final items to consider when writing applications that use
- the new V1.3 printer device. The first is, whenever the printer device
- is opened it grabs a copy of Preferences. For this reason, we recommend
- that when you want to print you open the printer device, print, and close
- the printer device. If you leave the printer device open you'll never
- know about user changes to Preferences.
-
- And finally, if your application is working in one bit plane (black&white)
- it is recommended that you perform a b&w (vs a grey-scale or color) dump
- as they are the fastest. Don't forget to set the threshold value.
-
-