home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / reference / amiga_mail_vol1 / printer / callingpd next >
Text File  |  1990-01-26  |  17KB  |  411 lines

  1. (c)  Copyright 1989 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice, and 
  3. is provided "as is" without warranty of any kind, either expressed or implied.  
  4. The entire risk as to the use of this information is assumed by the user.
  5.  
  6.  
  7.  
  8.            Programmer Notes on Calling the V1.3 Printer Device
  9.            ---------------------------------------------------
  10.  
  11.             by David Berezowski
  12.  
  13. The printer device has been exetensively revised under V1.3 of the Amiga 
  14. system software.  The following programmer's notes are presented to help
  15. you take full advantage of those changes in your application software.
  16. These notes assume that you are already familiar with how the printer
  17. device works - for more information, see the ROM Kernel manual.
  18.  
  19.  
  20. Arguments to DumpRPort
  21. ----------------------
  22.  
  23. io_Command      PRD_DUMPRPORT.
  24. io_RastPort     pointer to a RastPort - could be in fastmem.
  25. io_ColorMap     pointer to a ColorMap - could be your own custom one.
  26. io_Modes        the 'modes' flag from a ViewPort structure (you can fake
  27.                 it but the upper word is reserved and should be zero).
  28. io_SrcX            x offset into the RastPort to start printing from.
  29. io_SrcY            y offset into the RastPort to start printing from.
  30. io_SrcWidth     width of the RastPort to print from io_SrcX.
  31. io_SrcHeight    height of the RastPort to print from io_SrcY.
  32. io_DestCols     width of the printout in printer pixels.
  33. io_DestRows     height of the printout in printer pixels.
  34. io_Special      flag bits - these are explained below.
  35.  
  36.  
  37.  
  38. The Old Special Flags
  39. ---------------------
  40.  
  41. SPECIAL_MILROWS and SPECIAL_MILCOLS - the associated parameter is specified
  42. in thousandths of an inch on the printer;  ie. if DestCols = 8000, and
  43. DestRows = 10500 then the printout would be 8.000 x 10.500 inches.
  44.  
  45. SPECIAL_FULLROWS and SPECIAL_FULLCOLS - the specific dimension is set to the
  46. maximum possible as determined by the printer limits or the configuration
  47. limits, whichever is less.
  48.  
  49. SPECIAL_FRACROWS and SPECIAL_FRACCOLS - the associated parameter is taken 
  50. to be a longword binary fraction of the maximum for that dimension; ie. if
  51. SPECIAL_FRACCOLS is set and DestCols = 0x8000 then the width of the dumped
  52. picture would be 1/2 (0x8000 / 0xffff) the width of the paper.
  53.  
  54. SPECIAL_CENTER - the image will be automatically centered.
  55.  
  56. SPECIAL_ASPECT - one of the dimensions may be reduced or expanded to 
  57. preserve the aspect-ratio of the print.
  58.  
  59. SPECIAL_DENSITY (1-4) - see SPECIAL_DENSITY under the new flags section below.
  60.  
  61. SPECIAL_TRUSTME - the printer specific driver is instructed to not issue a
  62. reset command before and after the dump.  If this flag is NOT checked by the
  63. printer specific driver then setting this flag has no effect.  Since we now
  64. recommend that printer driver writers no longer issue a reset command (ever)
  65. it is probably a good idea to always set this flag when calling for a dump.
  66.  
  67.  
  68. The New Special Flags
  69. ---------------------
  70.  
  71. SPECIAL_DENSITY1 to SPECIAL_DENSITY7 - These were originally designed to allow
  72. a program to specify up to 7 print densities.  However, these flags are now
  73. obselete as they are overridden by the density setting in Preferences.  If you
  74. want to change the density, refer to the section on changing the printer 
  75. device's copy of Preferences.  The actual density in use can be determined by 
  76. a program using the SPECIAL_NOPRINT flag described below.
  77.  
  78. SPECIAL_NOFORMFEED - Allows for the mixing of text and graphics or multiple
  79. graphic dumps on page oriented printers (usually laser jet printers).  When
  80. this flag is set the page will not be ejected after a graphic dump.  If you
  81. perform another graphic dump without this flag set OR close the printer device
  82. after printing text after a graphic dump, the page will be ejected.  This
  83. flag MUST be set if you are doing strip printing (covered later on in this
  84. article).
  85.  
  86. SPECIAL_NOPRINT - Performs internal calculations, doesn't print and exits.
  87. This gives the calling program a chance to see what the printer specific
  88. values are for any given density.  This is useful for determine the dot 
  89. density and the maximum dots the printer has for any given density.  
  90.  
  91. This option also computes the final print size, and sets 'io_DestCols' and
  92. 'io_DestRows' in the calling program's 'IODRPReq' structure.  This allows 
  93. the calling program to see what the final print size would be in printer 
  94. pixels.  Note that it modifies the 'io_DestCols' and 'io_DestRows' fields of
  95. your 'IODRPReq' structure.
  96.  
  97.  
  98.  
  99. Data Structures
  100. ---------------
  101.  
  102. The printer data structures can be read once you have opened the printer
  103. device. Below is a code fragment to show how to do this.
  104.  
  105.     #include <exec/types.h>
  106.     #include <devices/printer.h>
  107.     #include <devices/prtbase.h>
  108.  
  109.     struct IODRPReq PReq;
  110.     struct PrinterData *PD;
  111.     struct PrinterExtendedData *PED;
  112.  
  113.     /* open the printer device  if it opened... */
  114.     if (OpenDevice("printer.device", 0, &PReq, 0) == NULL) {
  115.  
  116.         /* get pointer to printer data */
  117.         PD = (struct PrinterData *)PReq.io_Device;
  118.  
  119.         /* get pointer to printer extended data */
  120.         PED = &PD->pd_SegmentData->ps_PED;
  121.  
  122.         /* let's see what's there */
  123.         printf("PrinterName = '%s', Version=%u, Revision=%u",
  124.             PED->ped_PrinterName, PD->pd_SegmentData->ps_Version,
  125.             PD->pd_SegmentData->ps_Revision,);
  126.  
  127.         printf("PrinterClass=%u, ColorClass=%u",
  128.             PED->ped_PrinterClass, PED->ped_ColorClass);
  129.  
  130.         printf("MaxColumns=%u, NumCharSets=%u, NumRows=%u",
  131.             PED->ped_MaxColumns, PED->ped_NumCharSets,
  132.             PED->ped_NumRows);
  133.  
  134.         printf("MaxXDots=%lu, MaxYDots=%lu, XDotsInch=%u,YDotsInch=%u",
  135.             PED->ped_MaxXDots, PED->ped_MaxYDots,
  136.             PED->ped_XDotsInch, PED->ped_YDotsInch);
  137.  
  138.         CloseDevice(&PReq); /* close the printer device */
  139.     }
  140.  
  141. If you want the user to be able to access printer preferences without actually
  142. having to run Preferences (like DPAINT II's printer requester does), then use
  143. the code fragment above to examine the current settings.  This can be done by
  144. refering to 'PD->pd_Preferences'.  Note that the printer device must already
  145. be opened at this point.  
  146.  
  147. Next, put up a requester and allow the user to change whatever parameters
  148. they choose.  Remember, you are responsible for range checking these
  149. selections.  Listed below are the printer preferences items and their valid
  150. ranges.
  151.  
  152.  
  153. Text Preferences
  154. ----------------
  155. PrintPitch          - PICA, ELITE, FINE.
  156. PrintQuality        - DRAFT, LETTER.
  157. PrintSpacing        - SIX_LPI, EIGHT_LPI.
  158. PrintLeftMargin     - 1 to PrintRightMargin.
  159. PrintRightMargin    - PrintLeftMargin to 999.
  160. PaperLength         - 1 to 999.
  161.  
  162. Graphic Preferences
  163. -------------------
  164. PrintImage      - IMAGE_POSITIVE, IMAGE_NEGATIVE.
  165. PrintAspect     - ASPECT_HORIZ, ASPECT_VERT.
  166. PrintShade      - SHADE_BW, SHADE_GREYSCALE, SHADE_COLOR.
  167. PrintThreshold  - 1 to 15.
  168. PrintFlags      - CORRECT_RED, CORRECT_GREEN, CORRECT_BLUE, CENTER_IMAGE,
  169.                   IGNORE_DIMENSIONS, BOUNDED_DIMENSIONS, ABSOLUTE_DIMENSIONS,
  170.                   PIXEL_DIMENSIONS, MULTIPLY_DIMENSIONS, INTEGER_SCALING,
  171.                   ORDERED_DITHERING, HALFTONE_DITHERING, FLOYD_DITHERING,
  172.                   ANTI_ALIAS, GREY_SCALE2.
  173. PrintMaxWidth   - 0 to 65535.
  174. PrintMaxHeight  - 0 to 65535.
  175. PrintDensity    - 1 to 7.
  176. PrintXOffset    - 0 to 255.
  177.  
  178.  
  179. Asynchronous IO
  180. ---------------
  181.  
  182. We recommend that you use asynchronous IO for printing in your programs and
  183. give the user a way of aborting all requests.  Here are the notes on the 
  184. recommended way to do this.
  185.  
  186. To send requests for IO:
  187.  
  188.     struct IORequest *ioreq;
  189.     struct MsgPort *port;
  190.     UBYTE signal;
  191.  
  192.     port = ioreq->io_Message.mn_ReplyPort;
  193.     signal = port->mp_SigBit;
  194.  
  195.     SendIO(ioreq); /* send request */
  196.     Wait(signal); /* wait for completion (go to sleep) */
  197.     while ((Msg = GetMsg(port)) != NULL) { /* get ALL messages */
  198.     }
  199.  
  200.  
  201. To abort a previous request for IO use:
  202.  
  203.     struct IORequest *ioreq;
  204.  
  205.     AbortIO(ioreq); /* abort request */
  206.     WaitIO(ioreq); /* wait for reply */
  207.     /* at this point you can re-use 'ioreq'. */
  208.  
  209.  
  210. In the code fragments above 'ioreq' could be any one of:
  211.  
  212.     a) struct IOStdReq    /* a standard i/o request */
  213.     b) struct IODRPReq    /* a dumprport i/i request */
  214.     c) struct IOPrtCmdReq /* a printer command i/o request */
  215.  
  216.  
  217. Strip Printing
  218. --------------
  219.  
  220. Strip printing is a technique which allows you to print a picture that
  221. normally requires lots of memory when you only have a little to spare.
  222. This trick works by creating a temporary rastport as wide as your source
  223. rastport but not as high.  You then render a horizontal strip of your source
  224. rastport into the temporary rastport and dump it, moving down your rastport
  225. for each dump. 
  226.  
  227. The height of the strip must be an integer multiple of the printer's NumRows
  228. if you are doing a non-aspect-ratio-corrected picture.  You can find NumRows 
  229. by checking PED->ped_NumRows with the code fragment shown above. 
  230.  
  231. If you are doing an aspect-ratio-corrected picture then you'll have to use 
  232. the SPECIAL_NOPRINT flag to find a DestRows that is an integer multiple of 
  233. NumRows.  You do this by varying your source height and asking for a 
  234. SPECIAL_NOPRINT dump until DestRows comes back with a number that is an 
  235. integer multiple of NumRows. 
  236.  
  237. Another consideration to keep in mind is that DestRows should also be
  238. evenly divisible by 4 since the printer device uses a 4x4 dither matrix.
  239. You only need to worry about this if you are doing a grey-scale or color
  240. dump as b&w dumps do not do any dithering.  Fortunately most printers have
  241. a NumRows that is evenly divisible by 4.
  242.  
  243. If you are going to do strip printing and you want SMOOTHING to work across
  244. strip boundaries, you must add a raster line above and below the actual area
  245. that you are printing.  The line above should be the last line from the
  246. previous strip.  The line below should be the first line from the next strip.
  247. Don't forget to omit the line above on the first strip, and the line below
  248. on the last strip.
  249.  
  250. So if your source data is 200 lines high and you are printing in strips of
  251. 50 lines (ie. 4 separate dumps), your strip rastport will need to be 52 
  252. lines high.  Below is one scenario for doing the dump:
  253.  
  254.         1st strip - copy source line 0 thru 50 (51 lines) to strip rastport
  255.                     lines 0 thru 50 (51 lines).
  256.  
  257.                   - io_SrcY = 0, io_Height = 50.
  258.  
  259.                   - here the printer device can see that there is no line
  260.                     above the first line to dump (since SrcY = 0) and that
  261.                     there is a line below the last line to dump (since we
  262.                     have a 52 line rastport and are only dumping 51 lines).
  263.  
  264.  
  265.         2nd strip - copy source line 49 thru 100 (52 lines) to strip rastport
  266.                     lines 0 thru 51 (52 lines).
  267.  
  268.                   - io_SrcY = 1, io_Height = 50.
  269.  
  270.                   - here the printer device can see that there is a line
  271.                     above the first line to dump (since SrcY = 1) and that
  272.                     there is a line below the last line to dump (since we have
  273.                     a 52 line rastport and are only dumping 50 lines).
  274.  
  275.         3rd strip - copy source line 99 thru 150 (52 lines) to strip rastport
  276.                     lines 0 thru 51 (52 lines).
  277.  
  278.                   - io_SrcY = 1, io_Height = 50.
  279.  
  280.                   - here the printer device can see that there is a line
  281.                     above the first line to dump (since SrcY = 1) and that
  282.                     there is a line below the last line to dump (since we
  283.                     have a 52 line rastport and are only dumping 50 lines).
  284.         
  285.         4th strip - copy source line 149 thru 199 (51 lines) to strip rastport
  286.                     lines 1 thru 51 (51 lines).
  287.  
  288.                   - io_SrcY = 2, io_Height = 50.
  289.  
  290.                   - here the printer device can see that there is a line
  291.                     above the first line to dump (since SrcY = 2) and that
  292.                     there is no line below the last line to dump (since we
  293.                     have a 52 line rastport and are dumping only 50 lines).
  294.              
  295.  
  296. Error Codes
  297. -----------
  298.  
  299. If an error comes back to you please try and relay this back to the user
  300. instead of simply not printing.  Current errors and descriptions are:
  301.  
  302.     PDERR_NOERR        /* clean exit, no errors */
  303.     PDERR_CANCEL        /* user canceled print */
  304.     PDERR_NOTGRAPHICS    /* printer cannot output graphics */
  305.     PDERR_INVERTHAM        /* OBSOLETE */
  306.     PDERR_BADDIMENSION    /* print dimensions illegal */
  307.     PDERR_DIMENSIONOVFLOW    /* OBSOLETE */
  308.     PDERR_INTERNALMEMORY    /* no memory for internal variables */
  309.     PDERR_BUFFERMEMORY    /* no memory for print buffer */
  310.  
  311.  
  312. 12 Bit Planes
  313. -------------
  314.  
  315. The V1.3 printer device can dump up to 12 bit planes of data from either 
  316. chip or fast memory; use this to your advantage.  Assume we are using a 
  317. package called YAD (Yet Another Digitizer) that captures data as 24-bit RGB
  318. files and displays them on the Amiga in HAM mode.  When YAD goes to print 
  319. it simply does a screen dump of the HAM image.  
  320.  
  321. Well we all know that the HAM image is only an approximation of the real 
  322. colors.  Wouldn't it be nice if YAD had an option whereby it would build 
  323. a 12-bit plane image in fastmem and dump that to the printer.  This would
  324. produce much better looking output as each pixel could be any 1 of 4096
  325. colors - with none of the HAM limitations!
  326.  
  327.  
  328. Large Bit Maps
  329. --------------
  330.  
  331. Another new feature you can exploit is the ability of the V1.3 printer 
  332. device to dump very large bitmaps from either chip or fast memory.
  333. Suppose we have an application called YART (Yet Another Ray Tracer) that 
  334. ray traces images to the screen in 320x400 resolution.  When YART goes to
  335. print it simply does a screen dump of the low res 320x400 screen.  We 
  336. could expand the printed image to a size of 1280x1600 but then each single
  337. screen pixel is expanded to a (rather chunky) 4x4 block of printer pixels.
  338.  
  339. Wouldn't it be nice if YART had an option that would allow us to create a
  340. 1280x1600 image in fastmem or on disk and then dump that.  This would 
  341. produce a very impressive picture as 1 source pixel would correspond to 1 
  342. printer pixel (ie. no jaggies)!
  343.  
  344.  
  345. Aspect Ratio
  346. ------------
  347.  
  348. When dumping a non-displayed rastport you have two choices for aspect-ratio
  349. correction.  You can either do it yourself or let the printer device do it
  350. for you.
  351.  
  352.         Doing it Yourself
  353.  
  354.         a) You must look at the printer's XDotsInch and YDotsInch and
  355.            account for the fact that the printer may not have square
  356.            pixels.  You can then ask for a non-aspect-ratio-corrected
  357.            dump; probably a 1:1 dump.
  358.  
  359.         Letting the Printer Device Do It
  360.  
  361.         a) You could build your rastport such that the dimensions are an
  362.            integer multiple of one the Amiga's normal display resolutions
  363.            and then set the io_Modes argument to an appropriate value.
  364.        
  365.            For example, if your rasport dimensions were 1280 x 800 (an even
  366.            multiple of 640 x 400) you would want to set io_Modes to
  367.            'LACE | HIRES'.  Now the normal aspect-ratio correction code
  368.            of the printer device will work correctly (if you turn it on).
  369.  
  370.         b) You could build an arbitrary sized rastport and set
  371.            GfxBase->NormalDPMX and GfxBaseNormalDPYM to the dimensions
  372.            of your rastport.  You would then ask for a aspect-ratio-corrected
  373.            dump and the printer device will figure it all out.  If you use
  374.            this option you must restore GfxBase->NormalDPMX and
  375.            GfxBaseNormalDPYM to their previous values after the dump. 
  376.  
  377.            I know that math scholars among you are probably saying,
  378.            'Hey, if I have a square rastport, can't I just set DPMX and DPMY
  379.            both to 1?'.  Mathematically this is correct BUT for mysterious
  380.            reasons DPMX and DPMY must always be >= 182.  So if you have a
  381.            a square rastport you can set DPMX and DPMY to 182.
  382.  
  383.  
  384. 12 Bit Planes and Large Bit Maps
  385. --------------------------------
  386.  
  387. Obviously the above two techniques require that the system have quite
  388. a bit of memory floating around; but they do have their uses.  Large bit maps
  389. can be utilized by paint, desktop publishing, CAD and ray tracing programs
  390. to produce printed output to the resolution of the output device.  Remember
  391. that the printer's resolution can be determined programatically by looking at
  392. the PED structure discussed earlier.  Twelve bit plane rastports can be used
  393. to produce printed output which exceeds the Amiga's HAM display limitation. 
  394. Combining these two techniques can give amazingly good printed output.
  395.  
  396.  
  397. Miscellaneous Items
  398. -------------------
  399.  
  400. There are two final items to consider when writing applications that use
  401. the new V1.3 printer device.  The first is, whenever the printer device 
  402. is opened it grabs a copy of Preferences.  For this reason, we  recommend
  403. that when you want to print you open the printer device, print, and close
  404. the printer device.  If you leave the printer device open you'll never 
  405. know about user changes to Preferences.
  406.  
  407. And finally, if your application is working in one bit plane (black&white)
  408. it is recommended that you perform a b&w (vs a grey-scale or color) dump 
  409. as they are the fastest.  Don't forget to set the threshold value.
  410.  
  411.