home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* gdevamiga.c */
- /* Amiga driver for Ghostscript library, requires Kickstart 2.04 or higher */
-
- /* Written by Olaf `Olsen' Barthel, last change 29 January 1994
- *
- * My address: Olaf Barthel
- * Brabeckstrasse 35
- * D-30559 Hannover
- *
- * eMail: olsen@sourcery.han.de
- */
-
- #define CheckIO foo123
- #define ushort foo
-
- #include <intuition/intuitionbase.h>
- #include <intuition/gadgetclass.h>
- #include <intuition/imageclass.h>
- #include <intuition/icclass.h>
- #include <graphics/displayinfo.h>
- #include <libraries/iffparse.h>
- #include <graphics/gfxbase.h>
- #include <devices/printer.h>
- #include <devices/prtbase.h>
- #include <devices/prtgfx.h>
- #include <libraries/asl.h>
- #include <exec/memory.h>
- #include <clib/macros.h>
- #include <dos/dostags.h>
- #include <dos/rdargs.h>
- #include <dos/var.h>
- #include <dos/dos.h>
-
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/iffparse_protos.h>
- #include <clib/utility_protos.h>
- #include <clib/layers_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/asl_protos.h>
-
- /*
- #include <inline/stubs.h>
- #include <inline/iffparse.h>
- #include <inline/utility.h>
- #include <inline/exec.h>
- #include <inline/dos.h>
- */
-
- #include <string.h>
- #include <signal.h>
-
- #undef ushort
- #undef CheckIO
-
- struct IORequest *CheckIO(struct IORequest *);
-
- #include "gx.h" /* for gx_bitmap; includes std.h */
- #include "gsmatrix.h" /* needed for gxdevice.h */
- #include "gxdevice.h"
- #include "gserrors.h"
- #include "gsprops.h"
-
- /* Here is how to select a default page size format:
- *
- * Either enter include a line such as
- *
- * #define AMIGA_PAGE_A4 1
- *
- * Somewhere above in this module, or edit the makefile
- * to feature the option
- *
- * -dAMIGA_PAGE_A4
- *
- * among the device specific flags. Available default page
- * size formats are:
- *
- * AMIGA_PAGE_A4 European A4 page size (default)
- * AMIGA_PAGE_A3 European A3 page size
- * AMIGA_PAGE_LETTER US letter page size
- * AMIGA_PAGE_LEGAL US legal page size
- * AMIGA_PAGE_LEDGER US ledger paper size
- * AMIGA_PAGE_TABLOID US tabloid paper size
- */
-
- /* Select the default paper size if none specified. */
-
- #if !defined(AMIGA_PAGE_A4) && !defined(AMIGA_PAGE_A3) && !defined(AMIGA_PAGE_LETTER) && !defined(AMIGA_PAGE_LEGAL) && !defined(AMIGA_PAGE_LEDGER) && !defined(AMIGA_PAGE_TABLOID)
- /*#define AMIGA_PAGE_A4 1*/
- #define AMIGA_PAGE_A3 1
- #endif /* PAGE SIZE */
-
- /* A4 page size (in inches!) */
-
- #ifdef AMIGA_PAGE_A4
- #define DEFAULT_WIDTH 8.2
- #define DEFAULT_HEIGHT 11.6
- #endif /* AMIGA_PAGE_A4 */
-
- /* A3 page size */
-
- #ifdef AMIGA_PAGE_A3
- #define DEFAULT_WIDTH 11.6
- #define DEFAULT_HEIGHT 16.5
- #endif /* AMIGA_PAGE_A4 */
-
- /* US letter page size */
-
- #ifdef AMIGA_PAGE_LETTER
- #define DEFAULT_WIDTH 8.5
- #define DEFAULT_HEIGHT 11.0
- #endif /* AMIGA_PAGE_LETTER */
-
- /* US legal page size */
-
- #ifdef AMIGA_PAGE_LEGAL
- #define DEFAULT_WIDTH 8.5
- #define DEFAULT_HEIGHT 14.0
- #endif /* AMIGA_PAGE_LEGAL */
-
- /* US ledger page size */
-
- #ifdef AMIGA_PAGE_LEDGER
- #define DEFAULT_WIDTH 16.0
- #define DEFAULT_HEIGHT 11.0
- #endif /* AMIGA_PAGE_LEDGER */
-
- /* US tabloid page size */
-
- #ifdef AMIGA_PAGE_TABLOID
- #define DEFAULT_WIDTH 11.0
- #define DEFAULT_HEIGHT 17.0
- #endif /* AMIGA_PAGE_LEDGER */
-
- /* Default output file name. */
-
- #define DEFAULT_FILENAME "gs_page"
-
- /* Turn a byte into a 24 bit colour value. */
-
- #define SPREAD(i) ((ULONG)(i) << 24 | (ULONG)(i) << 16 | (ULONG)(i) << 8 | (i))
-
- /* Scroller gadget IDs. */
-
- enum { VERTICAL_SCROLLER, HORIZONTAL_SCROLLER,
- UP_ARROW, DOWN_ARROW,
- LEFT_ARROW, RIGHT_ARROW,
-
- GADGET_COUNT };
-
- /* Scroller arrow IDs. */
-
- enum { UP_IMAGE, DOWN_IMAGE,
- LEFT_IMAGE, RIGHT_IMAGE,
-
- IMAGE_COUNT };
-
- /* Codes for the MoveAround() routine. */
-
- enum { MOVE_MIN,MOVE_FAR_DOWN,MOVE_DOWN,MOVE_UP,MOVE_FAR_UP,MOVE_MAX };
-
- /* Some handy bit masks. */
-
- #define SIG_KILL SIGBREAKF_CTRL_C
- #define SIG_HANDSHAKE SIGF_SINGLE
-
- /* Static dimensions of scroller arrows. */
-
- #define ARROW_WIDTH 16
- #define ARROW_HEIGHT 11
-
- /* The `Help' key raw code. */
-
- #define HELP_CODE 95
-
- /* Minimum window inner area dimension. */
-
- #define MINIMUM_WIDTH 64
- #define MINIMUM_HEIGHT 32
-
- /* Handy superbitmap window macros. */
-
- #define LAYERXOFFSET(w) ((w) -> RPort -> Layer -> Scroll_X)
- #define LAYERYOFFSET(w) ((w) -> RPort -> Layer -> Scroll_Y)
-
- /* User input to listen to. */
-
- #define IDCMP_FLAGS (IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_MOUSEMOVE | IDCMP_NEWSIZE | IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_RAWKEY)
-
- /* Chunk IDs. */
-
- #define ID_ILBM MAKE_ID('I','L','B','M')
- #define ID_BMHD MAKE_ID('B','M','H','D')
- #define ID_CMAP MAKE_ID('C','M','A','P')
- #define ID_CAMG MAKE_ID('C','A','M','G')
- #define ID_ANNO MAKE_ID('A','N','N','O')
- #define ID_DPI MAKE_ID('D','P','I',' ')
- #define ID_BODY MAKE_ID('B','O','D','Y')
-
- /* Chunk contents definitions. */
-
- typedef struct
- {
- UWORD w,h; /* raster width & height in pixels */
- WORD x,y; /* position for this image */
- UBYTE nPlanes; /* # source bitplanes */
- UBYTE masking; /* masking technique */
- UBYTE compression; /* compression algoithm */
- UBYTE pad1; /* UNUSED. For consistency, put 0 here.*/
- UWORD transparentColor; /* transparent "color number" */
- UBYTE xAspect,yAspect; /* aspect ratio, a rational number x/y */
- WORD pageWidth,pageHeight; /* source "page" size in pixels */
- } BitMapHeader;
-
- typedef struct
- {
- UWORD dpi_x;
- UWORD dpi_y;
- } DPIHeader;
-
- /* Packer modes. */
-
- #define DUMP 0
- #define RUN 1
-
- /* Minimum data run size, maximum data run size and maximum cache size. */
-
- #define MINRUN 3
- #define MAXRUN 128
- #define MAXDAT 128
-
- /* This module actually implements four different Amiga based
- * devices. As the rendering operations are all the same,
- * one single device definition is sufficient.
- */
-
- typedef struct gx_device_amiga
- {
- gx_device_common;
-
- struct Screen *screen; /* Any screen */
- struct Window *window; /* Some window to be opened on the Workbench screen */
-
- LONG super_width, /* Superbitmap width */
- super_height; /* Superbitmap height */
-
- struct BitMap *super_bitmap; /* Window superbitmap area */
- struct Gadget **gadget; /* Scroller gadgets */
- struct Image **image; /* Scroller arrow images */
-
- struct Task *dispatcher; /* Slider dispatch task */
- struct Process *main; /* Main program */
-
- struct RastPort *rport; /* Rendering area */
-
- struct IODRPReq *printer; /* Printer interface data */
- struct MsgPort *port; /* Printer io data */
-
- struct ColorMap *colormap; /* A black/white colour map */
- struct BitMap *bitmap; /* Rendering bitmap data */
- PLANEPTR bitplane; /* Rendering raster */
-
- gx_color_index last_pen; /* The last colour set */
-
- float page_width, /* The page width */
- page_height; /* The page height */
- char file_name[256];/* The output file name */
- int page_count; /* The page number counter */
-
- int cube_size; /* Colour cube size, 0 for b/w */
- struct RastPort *temp_rport; /* Temporary raster port for pixmap imaging. */
- UBYTE *temp_array; /* Temporary colour manipulation array. */
- LONG *pens;
- } gx_device_amiga;
-
- /* Function prototypes */
-
- VOID set_mono_device(gx_device_amiga *dev);
- VOID set_colour_device(gx_device_amiga *dev,int cube_size,LONG *pens);
- VOID set_colour_printer_device(gx_device_amiga *dev,LONG CubeSize);
- VOID DeleteBitMap(struct BitMap *BitMap,BOOL Private);
- struct BitMap * CreateBitMap(LONG Width,LONG Height,LONG Depth,ULONG Flags,struct BitMap *Friend,BOOL Private);
- VOID DeleteTempRPort(struct RastPort *Temp);
- struct RastPort * CreateTempRPort(struct RastPort *Source);
- LONG Euclid(LONG a,LONG b);
- BYTE * PutDump(register BYTE *Destination,register LONG Count);
- BYTE * PutRun(register BYTE *Destination,LONG Count,WORD Char);
- LONG PackRow(PLANEPTR *SourcePtr,register BYTE *Destination,LONG RowSize);
- BOOL PutBODY(struct IFFHandle *Handle,struct BitMap *BitMap);
- BOOL PutANNO(struct IFFHandle *Handle);
- BOOL PutCAMG(struct IFFHandle *Handle);
- BOOL PutCMAP(struct IFFHandle *Handle);
- BOOL PutDPI(struct IFFHandle *Handle,UWORD X_DPI,UWORD Y_DPI);
- BOOL PutBMHD(struct IFFHandle *Handle,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI);
- BOOL SaveBitMap(STRPTR Name,struct BitMap *BitMap,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI);
- float GetInches(STRPTR Buffer);
- VOID DispatchTask(VOID);
- VOID DeleteScrollers(gx_device *dev);
- BOOL CreateScrollers(gx_device *dev,struct Screen *Screen);
- VOID WindowResize(gx_device *dev);
- VOID WindowUpdate(struct Gadget *Gadget,gx_device *dev);
- VOID MoveAround(struct Gadget *Gadget,LONG How,gx_device *dev);
- VOID DispatchSuperWindow(gx_device *dev);
- void devcleanup(VOID);
- gx_color_index amiga_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue);
- int amiga_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3]);
- LONG * AllocatePens(struct ViewPort *VPort,LONG CubeSize);
- int amiga_open_default(gx_device *dev);
- int amiga_open_low(gx_device *dev);
- int amiga_open_high(gx_device *dev);
- int amiga_open_super(gx_device *dev);
- int amiga_open_a2024(gx_device *dev);
- int amiga_open_picassoii(gx_device *dev);
- int amiga_open_custom(gx_device *dev);
- int amiga_open_printer(gx_device *dev);
- int amiga_output_page_printer(gx_device *dev,int num_copies,int flush);
- int amiga_close_printer(gx_device *dev);
- int amiga_get_bits(gx_device *dev,int y,byte *str,byte **actual_data);
- int amiga_open(gx_device *dev,ULONG Mode);
- int amiga_output_page(gx_device *dev,int num_copies,int flush);
- int amiga_close(gx_device *dev);
- int amiga_fill_rectangle(gx_device *dev,int x,int y,int w,int h,gx_color_index color);
- int amiga_copy_mono(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one);
- int amiga_copy_color(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h);
- int amiga_draw_line(gx_device *dev,int x0,int y0,int x1,int y1,gx_color_index color);
- int amiga_copy_mono_raw(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one);
- int amiga_copy_color_raw(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h);
- int amiga_fill_rectangle_raw(gx_device *dev,int x,int y,int w,int h,gx_color_index color);
- int amiga_draw_line_raw(gx_device *dev,int x,int y,int x1,int y1,gx_color_index color);
- int amiga_open_ilbm(gx_device *dev);
- int amiga_output_page_ilbm(gx_device *dev,int num_copies,int flush);
- int amiga_close_ilbm(gx_device *dev);
- int amiga_get_props(gx_device *dev,gs_prop_item *plist);
- int amiga_put_props(gx_device *dev,gs_prop_item *plist,int count);
- gx_color_index amiga_color_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue);
- int amiga_color_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3]);
- gx_color_index amiga_color_map_rgb_color_pen(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue);
- int amiga_color_map_color_rgb_pen(gx_device *dev,gx_color_index color,gx_color_value rgb[3]);
- int amiga_copy_color8(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h);
- int amiga_copy_mono_raw_color(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one);
- int amiga_copy_color_raw_color16(gx_device *dev,const UBYTE *data,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h);
- int amiga_fill_rectangle_raw_color(gx_device *dev,int x,int y,int w,int h,gx_color_index color);
- int amiga_draw_line_raw_color(gx_device *dev,int x,int y,int x1,int y1,gx_color_index color);
-
- /* External reference to some libraries, required for version checking, etc. */
-
- extern struct GfxBase *GfxBase;
- extern struct Library *AslBase;
-
- /* Number of packed bytes and pack buffer. */
-
- LONG PackedBytes;
- BYTE Buffer[MAXDAT + 1];
-
- /* Bit masks. */
-
- STATIC UBYTE shift[8] = { 128, 64, 32, 16, 8, 4, 2, 1 },
- masks[8] = { 127,191,223,239,247,251,253,254 };
-
- /* Device routine jump tables */
-
- STATIC gx_device_procs amiga_default_procs =
- {
- amiga_open_default,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- amiga_output_page,
- amiga_close,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle,
- gx_default_tile_rectangle,
- amiga_copy_mono,
- amiga_copy_color,
- amiga_draw_line,
- gx_default_get_bits,
- amiga_get_props,
- amiga_put_props
- };
-
- STATIC gx_device_procs amiga_low_procs =
- {
- amiga_open_low,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- amiga_output_page,
- amiga_close,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle,
- gx_default_tile_rectangle,
- amiga_copy_mono,
- amiga_copy_color,
- amiga_draw_line,
- gx_default_get_bits,
- amiga_get_props,
- amiga_put_props
- };
-
- STATIC gx_device_procs amiga_high_procs =
- {
- amiga_open_high,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- amiga_output_page,
- amiga_close,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle,
- gx_default_tile_rectangle,
- amiga_copy_mono,
- amiga_copy_color,
- amiga_draw_line,
- gx_default_get_bits,
- amiga_get_props,
- amiga_put_props
- };
-
- STATIC gx_device_procs amiga_super_procs =
- {
- amiga_open_super,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- amiga_output_page,
- amiga_close,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle,
- gx_default_tile_rectangle,
- amiga_copy_mono,
- amiga_copy_color,
- amiga_draw_line,
- gx_default_get_bits,
- amiga_get_props,
- amiga_put_props
- };
-
- STATIC gx_device_procs amiga_a2024_procs =
- {
- amiga_open_a2024,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- amiga_output_page,
- amiga_close,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle,
- gx_default_tile_rectangle,
- amiga_copy_mono,
- amiga_copy_color,
- amiga_draw_line,
- gx_default_get_bits,
- amiga_get_props,
- amiga_put_props
- };
-
- STATIC gx_device_procs amiga_picassoii_procs =
- {
- amiga_open_picassoii,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- amiga_output_page,
- amiga_close,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle,
- gx_default_tile_rectangle,
- amiga_copy_mono,
- amiga_copy_color,
- amiga_draw_line,
- gx_default_get_bits,
- amiga_get_props,
- amiga_put_props
- };
-
- STATIC gx_device_procs amiga_custom_procs =
- {
- amiga_open_custom,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- amiga_output_page,
- amiga_close,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle,
- gx_default_tile_rectangle,
- amiga_copy_mono,
- amiga_copy_color,
- amiga_draw_line,
- gx_default_get_bits,
- amiga_get_props,
- amiga_put_props
- };
-
- STATIC gx_device_procs amiga_printer_procs =
- {
- amiga_open_printer,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- amiga_output_page_printer,
- amiga_close_printer,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle_raw,
- gx_default_tile_rectangle,
- amiga_copy_mono_raw,
- amiga_copy_color_raw,
- amiga_draw_line_raw,
- amiga_get_bits,
- amiga_get_props,
- amiga_put_props
- };
-
- STATIC gx_device_procs amiga_ilbm_procs =
- {
- amiga_open_ilbm,
- gx_default_get_initial_matrix,
- gx_default_sync_output,
- amiga_output_page_ilbm,
- amiga_close_ilbm,
- amiga_map_rgb_color,
- amiga_map_color_rgb,
- amiga_fill_rectangle_raw,
- gx_default_tile_rectangle,
- amiga_copy_mono_raw,
- amiga_copy_color_raw,
- amiga_draw_line_raw,
- amiga_get_bits,
- amiga_get_props,
- amiga_put_props
- };
-
- /* Default device: opens a window on the Workbench screen and renders into it */
-
- gx_device_amiga gs_amiga_device =
- {
- sizeof(gx_device_amiga), /* params_size */
- &amiga_default_procs, /* procs */
- "amiga", /* dname */
- 0, 0, /* width, height */
- 72.27, 72.27, /* xdpi, ydpi */
- no_margins, /* margins */
- dci_black_and_white, /* color info */
- 0, /* is_open */
-
- NULL, /* screen */
- NULL, /* window */
-
- 0, /* super_width */
- 0, /* super_height */
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_WIDTH, /* page width */
- DEFAULT_HEIGHT, /* page height */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* Low resolution device: opens a lores custom screen and renders into it */
-
- gx_device_amiga gs_amiga_low_device =
- {
- sizeof(gx_device_amiga), /* params_size */
- &amiga_low_procs, /* procs */
- "amiga_low", /* dname */
- 0, 0, /* width, height */
- 72.27, 72.27, /* xdpi, ydpi */
- no_margins, /* margins */
- dci_black_and_white, /* color info */
- 0, /* is_open */
-
- NULL, /* screen */
- NULL, /* window */
-
- 0, /* super_width */
- 0, /* super_height */
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_WIDTH, /* page width */
- DEFAULT_HEIGHT, /* page height */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* High resolution device: opens a highres-interlaced custom screen */
-
- gx_device_amiga gs_amiga_high_device =
- {
- sizeof(gx_device_amiga), /* params_size */
- &amiga_high_procs, /* procs */
- "amiga_high", /* dname */
- 0, 0, /* width, height */
- 72.27, 72.27, /* xdpi, ydpi */
- no_margins, /* margins */
- dci_black_and_white, /* color info */
- 0, /* is_open */
-
- NULL, /* screen */
- NULL, /* window */
-
- 0, /* super_width */
- 0, /* super_height */
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_WIDTH, /* page width */
- DEFAULT_HEIGHT, /* page height */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* Super high resolution device: opens a super-highres-interlaced custom screen */
-
- gx_device_amiga gs_amiga_super_device =
- {
- sizeof(gx_device_amiga), /* params_size */
- &amiga_super_procs, /* procs */
- "amiga_super", /* dname */
- 0, 0, /* width, height */
- 72.27, 72.27, /* xdpi, ydpi */
- no_margins, /* margins */
- dci_black_and_white, /* color info */
- 0, /* is_open */
-
- NULL, /* screen */
- NULL, /* window */
-
- 0, /* super_width */
- 0, /* super_height */
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_WIDTH, /* page width */
- DEFAULT_HEIGHT, /* page height */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* A2024 device: opens an A2024 custom screen */
-
- gx_device_amiga gs_amiga_a2024_device =
- {
- sizeof(gx_device_amiga), /* params_size */
- &amiga_a2024_procs, /* procs */
- "amiga_a2024", /* dname */
- 0, 0, /* width, height */
- 72.27, 72.27, /* xdpi, ydpi */
- no_margins, /* margins */
- dci_black_and_white, /* color info */
- 0, /* is_open */
-
- NULL, /* screen */
- NULL, /* window */
-
- 0, /* super_width */
- 0, /* super_height */
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_WIDTH, /* page width */
- DEFAULT_HEIGHT, /* page height */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* Picasso II device: opens a Picasso II custom screen */
-
- gx_device_amiga gs_amiga_picassoii_device =
- {
- sizeof(gx_device_amiga), /* params_size */
- &amiga_picassoii_procs, /* procs */
- "amiga_picassoii", /* dname */
- 0, 0, /* width, height */
- 72.27, 72.27, /* xdpi, ydpi */
- no_margins, /* margins */
- dci_black_and_white, /* color info */
- 0, /* is_open */
-
- NULL, /* screen */
- NULL, /* window */
-
- 0, /* super_width */
- 0, /* super_height */
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_WIDTH, /* page width */
- DEFAULT_HEIGHT, /* page height */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* Custom device: opens a custom screen, will ask for screen mode or check env variable. */
-
- gx_device_amiga gs_amiga_custom_device =
- {
- sizeof(gx_device_amiga), /* params_size */
- &amiga_custom_procs, /* procs */
- "amiga_custom", /* dname */
- 0, 0, /* width, height */
- 72.27, 72.27, /* xdpi, ydpi */
- no_margins, /* margins */
- dci_black_and_white, /* color info */
- 0, /* is_open */
-
- NULL, /* screen */
- NULL, /* window */
-
- 0, /* super_width */
- 0, /* super_height */
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_WIDTH, /* page width */
- DEFAULT_HEIGHT, /* page height */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* Printer device: renders the imagery and sends it to the printer */
-
- gx_device_amiga gs_amiga_printer_device =
- {
- sizeof(gx_device_amiga), /* params_size */
- &amiga_printer_procs, /* procs */
- "amiga_printer", /* dname */
- 0, 0, /* width, height */
- 72.27, 72.27, /* xdpi, ydpi */
- no_margins, /* margins */
- dci_black_and_white, /* color info */
- 0, /* is_open */
-
- NULL, /* screen */
- NULL, /* window */
-
- 0, /* super_width */
- 0, /* super_height */
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_WIDTH, /* page width */
- DEFAULT_HEIGHT, /* page height */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* ILBM device: renders the imagery and saves it to an IFF-ILBM file. */
-
- gx_device_amiga gs_amiga_ilbm_device =
- {
- sizeof(gx_device_amiga), /* params_size */
- &amiga_ilbm_procs, /* procs */
- "amiga_ilbm", /* dname */
- 0, 0, /* width, height */
- 72.27, 72.27, /* xdpi, ydpi */
- no_margins, /* margins */
- dci_black_and_white, /* color info */
- 0, /* is_open */
-
- NULL, /* screen */
- NULL, /* window */
-
- 0, /* super_width */
- 0, /* super_height */
- NULL, /* super_bitmap */
- NULL, /* gadget */
- NULL, /* image */
-
- NULL, /* dispatcher */
- NULL, /* main */
-
- NULL, /* rport */
-
- NULL, /* printer */
- NULL, /* port */
- NULL, /* colormap */
- NULL, /* bitmap */
- NULL, /* bitplane */
-
- 1, /* last_pen */
-
- DEFAULT_WIDTH, /* page width */
- DEFAULT_HEIGHT, /* page height */
- DEFAULT_FILENAME, /* output file */
- 1, /* page counter */
-
- 0, /* cube_size */
- NULL, /* temp_rport */
- NULL, /* temp_array */
- NULL /* pens */
- };
-
- /* Dark (black) and light (white) rendering colours; the default device
- * determines the actual colours to be used by looking into the screen
- * colour lookup table, the other device drivers leave these values
- * untouched.
- */
-
- STATIC UBYTE DarkPen = 0,
- LightPen = 1;
-
- /* Cheap, but effective ;-) */
-
- #define xdev ((gx_device_amiga *)dev)
-
- /* set_mono_device(gx_device_amiga *dev,int cube_size,LONG *pens):
- *
- * Reconfigure a device for monochrome output.
- */
-
- VOID
- set_mono_device(gx_device_amiga *dev)
- {
- xdev -> color_info . depth = 1;
- xdev -> color_info . num_components = 1;
- xdev -> color_info . max_gray = 1;
- xdev -> color_info . max_rgb = 0;
- xdev -> color_info . dither_gray = 2;
- xdev -> color_info . dither_rgb = 0;
-
- xdev -> procs -> copy_color = amiga_copy_color;
- xdev -> procs -> map_rgb_color = amiga_map_rgb_color;
- xdev -> procs -> map_color_rgb = amiga_map_color_rgb;
-
- xdev -> cube_size = 0;
- }
-
- /* set_colour_device(gx_device_amiga *dev,int cube_size,LONG *pens):
- *
- * Reconfigure a device for colour output.
- */
-
- VOID
- set_colour_device(gx_device_amiga *dev,int cube_size,LONG *pens)
- {
- xdev -> color_info . depth = 8;
- xdev -> color_info . num_components = 3;
- xdev -> color_info . max_gray = cube_size - 1;
- xdev -> color_info . max_rgb = cube_size - 1;
- xdev -> color_info . dither_gray = cube_size;
- xdev -> color_info . dither_rgb = cube_size;
-
- xdev -> procs -> copy_color = amiga_copy_color8;
-
- /* Any colours to be remapped? */
-
- if(pens)
- {
- xdev -> procs -> map_rgb_color = amiga_color_map_rgb_color_pen;
- xdev -> procs -> map_color_rgb = amiga_color_map_color_rgb_pen;
- xdev -> pens = pens;
- }
- else
- {
- xdev -> procs -> map_rgb_color = amiga_color_map_rgb_color;
- xdev -> procs -> map_color_rgb = amiga_color_map_color_rgb;
- }
-
- /* Remember the size of the RGB cube. */
-
- xdev -> cube_size = cube_size;
- }
-
- /* set_colour_printer_device(gx_device_amiga *dev,LONG CubeSize):
- *
- * Configure the printer device for colour output.
- */
-
- VOID
- set_colour_printer_device(gx_device_amiga *dev,LONG CubeSize)
- {
- xdev -> color_info . depth = 16;
- xdev -> color_info . num_components = 3;
- xdev -> color_info . max_gray = CubeSize - 1;
- xdev -> color_info . max_rgb = CubeSize - 1;
- xdev -> color_info . dither_gray = CubeSize;
- xdev -> color_info . dither_rgb = CubeSize;
-
- xdev -> procs -> fill_rectangle = amiga_fill_rectangle_raw_color;
- xdev -> procs -> copy_mono = amiga_copy_mono_raw_color;
- xdev -> procs -> copy_color = amiga_copy_color_raw_color16;
- xdev -> procs -> draw_line = amiga_draw_line_raw_color;
- xdev -> procs -> get_bits = gx_default_get_bits;
- xdev -> procs -> map_rgb_color = amiga_color_map_rgb_color;
- xdev -> procs -> map_color_rgb = amiga_color_map_color_rgb;
- xdev -> cube_size = CubeSize;
- }
-
- /* DeleteBitMap(struct BitMap *BitMap,BOOL Private):
- *
- * Free memory associated with a custom rendering bitmap.
- */
-
- VOID
- DeleteBitMap(struct BitMap *BitMap,BOOL Private)
- {
- if(GfxBase -> LibNode . lib_Version >= 39 && !Private)
- FreeBitMap(BitMap);
- else
- {
- LONG i;
-
- for(i = 0 ; i < BitMap -> Depth ; i++)
- {
- if(BitMap -> Planes[i])
- FreeVec(BitMap -> Planes[i]);
- }
-
- FreeVec(BitMap);
- }
- }
-
- /* CreateBitMap(LONG Width,LONG Height,LONG Depth,ULONG Flags,struct BitMap *Friend,BOOL Private):
- *
- * Create a custom rendering bitmap.
- */
-
- struct BitMap *
- CreateBitMap(LONG Width,LONG Height,LONG Depth,ULONG Flags,struct BitMap *Friend,BOOL Private)
- {
- if(GfxBase -> LibNode . lib_Version >= 39 && !Private)
- return(AllocBitMap(Width,Height,Depth,Flags,Friend));
- else
- {
- struct BitMap *BitMap;
- LONG Plus;
- ULONG MemType;
-
- /* Bitmap structure needs to be padded if more
- * than the standard eight bitplanes are to be
- * allocated.
- */
-
- if(Depth > 8)
- Plus = (Depth - 8) * sizeof(PLANEPTR);
- else
- Plus = 0;
-
- if(Private)
- MemType = MEMF_ANY;
- else
- MemType = MEMF_CHIP;
-
- if(BitMap = (struct BitMap *)AllocVec(sizeof(struct BitMap) + Plus,MEMF_ANY | MEMF_CLEAR))
- {
- LONG i,PageSize;
-
- InitBitMap(BitMap,Depth,Width,Height);
-
- PageSize = BitMap -> BytesPerRow * BitMap -> Rows;
-
- for(i = 0 ; i < BitMap -> Depth ; i++)
- {
- if(!(BitMap -> Planes[i] = (PLANEPTR)AllocVec(PageSize,MemType)))
- {
- LONG j;
-
- for(j = 0 ; j < i ; j++)
- FreeVec(BitMap -> Planes[j]);
-
- FreeVec(BitMap);
-
- return(NULL);
- }
- }
-
- return(BitMap);
- }
- }
- }
-
- /* DeleteTempRPort(struct RastPort *Temp):
- *
- * Free memory associated with a temporary raster port.
- */
-
- VOID
- DeleteTempRPort(struct RastPort *Temp)
- {
- DeleteBitMap(Temp -> BitMap,FALSE);
-
- FreeVec(Temp);
- }
-
- /* CreateTempRPort(struct RastPort *Source):
- *
- * Allocate memory for temporary raster port (one line high).
- */
-
- struct RastPort *
- CreateTempRPort(struct RastPort *Source)
- {
- struct RastPort *Temp;
-
- if(Temp = (struct RastPort *)AllocVec(sizeof(struct RastPort),MEMF_ANY))
- {
- LONG Width,Depth;
-
- CopyMem(Source,Temp,sizeof(struct RastPort));
-
- Temp -> Layer = NULL;
-
- if(GfxBase -> LibNode . lib_Version >= 39)
- {
- Width = GetBitMapAttr(Source -> BitMap,BMA_WIDTH);
- Depth = GetBitMapAttr(Source -> BitMap,BMA_DEPTH);
- }
- else
- {
- Width = Source -> BitMap -> BytesPerRow * 8;
- Depth = Source -> BitMap -> Depth;
- }
-
- if(Temp -> BitMap = CreateBitMap(Width,1,Depth,NULL,Source -> BitMap,FALSE))
- return(Temp);
- else
- FreeVec(Temp);
- }
-
- return(NULL);
- }
-
- /* Euclid(LONG a,LONG b):
- *
- * Compute the greatest common divisor of two integers.
- */
-
- LONG
- Euclid(LONG a,LONG b)
- {
- do
- {
- if(a < b)
- {
- LONG t;
-
- t = a;
- a = b;
- b = t;
- }
-
- a = a % b;
- }
- while(a);
-
- return(b);
- }
-
- /* PutDump(register BYTE *Destination,register LONG Count):
- *
- * Store a byte dump.
- */
-
- BYTE *
- PutDump(register BYTE *Destination,register LONG Count)
- {
- register BYTE *Source = Buffer;
-
- *Destination++ = Count - 1;
- PackedBytes += Count + 1;
-
- while(Count--)
- *Destination++ = *Source++;
-
- return(Destination);
- }
-
- /* PutRun(register BYTE *Destination,LONG Count,WORD Char):
- *
- * Store a byte run.
- */
-
- BYTE *
- PutRun(register BYTE *Destination,LONG Count,WORD Char)
- {
- *Destination++ = -(Count - 1);
- *Destination++ = Char;
- PackedBytes += 2;
-
- return(Destination);
- }
-
- /* PackRow(PLANEPTR *SourcePtr,register BYTE *Destination,LONG RowSize):
- *
- * Pack a raster line using the CmpByteRun1 algorithm.
- */
-
- LONG
- PackRow(PLANEPTR *SourcePtr,register BYTE *Destination,LONG RowSize)
- {
- register BYTE *Source = *SourcePtr;
-
- WORD Buffered = 1,
- RunStart = 0;
- BYTE Mode = DUMP,
- LastChar,
- Char;
-
- PackedBytes = 0;
-
- Buffer[0] = LastChar = Char = *Source++;
-
- RowSize--;
-
- while(RowSize--)
- {
- Buffer[Buffered++] = Char = *Source++;
-
- if(Mode)
- {
- if((Char != LastChar) || (Buffered - RunStart > MAXRUN))
- {
- Destination = PutRun(Destination,Buffered - 1 - RunStart,LastChar);
- Buffer[0] = Char;
- Buffered = 1;
- RunStart = 0;
- Mode = DUMP;
- }
- }
- else
- {
- if(Buffered > MAXDAT)
- {
- Destination = PutDump(Destination,Buffered - 1);
- Buffer[0] = Char;
- Buffered = 1;
- RunStart = 0;
- }
- else
- {
- if(Char == LastChar)
- {
- if(Buffered - RunStart >= MINRUN)
- {
- if(RunStart)
- Destination = PutDump(Destination,RunStart);
-
- Mode = RUN;
- }
- else
- {
- if(!RunStart)
- Mode = RUN;
- }
- }
- else
- RunStart = Buffered - 1;
- }
- }
-
- LastChar = Char;
- }
-
- if(Mode)
- PutRun(Destination,Buffered - RunStart,LastChar);
- else
- PutDump(Destination,Buffered);
-
- *SourcePtr = Source;
-
- return(PackedBytes);
- }
-
- /* PutBODY(struct IFFHandle *Handle,struct BitMap *BitMap):
- *
- * Store a bitmap in a BODY chunk.
- */
-
- BOOL
- PutBODY(struct IFFHandle *Handle,struct BitMap *BitMap)
- {
- PLANEPTR *Planes;
- BYTE *PackBuffer;
- BOOL Success = FALSE;
- LONG PackedBytes,
- i,j;
-
- /* Allocate the bitplane information. */
-
- if(Planes = (PLANEPTR *)AllocVec(BitMap -> Depth * sizeof(PLANEPTR *),MEMF_ANY | MEMF_CLEAR))
- {
- /* Allocate the compression buffer. */
-
- if(PackBuffer = (BYTE *)AllocVec(BitMap -> BytesPerRow * 2,MEMF_ANY))
- {
- /* Copy the planes over. */
-
- for(i = 0 ; i < BitMap -> Depth ; i++)
- Planes[i] = BitMap -> Planes[i];
-
- if(!PushChunk(Handle,0,ID_BODY,IFFSIZE_UNKNOWN))
- {
- Success = TRUE;
-
- /* Run down the rows. */
-
- for(i = 0 ; Success && i < BitMap -> Rows ; i++)
- {
- for(j = 0 ; Success && j < BitMap -> Depth ; j++)
- {
- /* Pack the data. */
-
- PackedBytes = PackRow(&Planes[j],PackBuffer,BitMap -> BytesPerRow);
-
- /* Write it to disk. */
-
- if(WriteChunkRecords(Handle,PackBuffer,PackedBytes,1) != 1)
- Success = FALSE;
- }
- }
-
- if(PopChunk(Handle))
- Success = FALSE;
- }
-
- FreeVec(PackBuffer);
- }
-
- FreeVec(Planes);
- }
-
- return(Success);
- }
-
- /* PutANNO(struct IFFHandle *Handle):
- *
- * Store annotation chunk.
- */
-
- BOOL
- PutANNO(struct IFFHandle *Handle)
- {
- STATIC STRPTR Note = "Rendered by GNU Ghostscript 2.6.0";
-
- if(!PushChunk(Handle,0,ID_ANNO,strlen(Note)))
- {
- if(WriteChunkRecords(Handle,Note,strlen(Note),1) == 1)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* PutCAMG(struct IFFHandle *Handle):
- *
- * Store display mode chunk.
- */
-
- BOOL
- PutCAMG(struct IFFHandle *Handle)
- {
- ULONG ViewModes = HIRESLACE_KEY;
-
- if(!PushChunk(Handle,0,ID_CAMG,sizeof(ULONG)))
- {
- if(WriteChunkRecords(Handle,&ViewModes,sizeof(ULONG),1) == 1)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* PutCMAP(struct IFFHandle *Handle):
- *
- * Store colour map chunk.
- */
-
- BOOL
- PutCMAP(struct IFFHandle *Handle)
- {
- STATIC UBYTE Colours[2][3] =
- {
- 0x00,0x00,0x00,
- 0xFF,0xFF,0xFF
- };
-
- if(!PushChunk(Handle,0,ID_CMAP,sizeof(Colours)))
- {
- if(WriteChunkRecords(Handle,Colours,2,3) == 3)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* PutDPI(struct IFFHandle *Handle,UWORD X_DPI,UWORD Y_DPI):
- *
- * Store DPI chunk.
- */
-
- BOOL
- PutDPI(struct IFFHandle *Handle,UWORD X_DPI,UWORD Y_DPI)
- {
- DPIHeader Header;
-
- Header . dpi_x = X_DPI;
- Header . dpi_y = Y_DPI;
-
- if(!PushChunk(Handle,0,ID_DPI,sizeof(Header)))
- {
- if(WriteChunkRecords(Handle,&Header,sizeof(Header),1) == 1)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- /* PutBMHD(struct IFFHandle *Handle,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI):
- *
- * Store BMHD chunk.
- */
-
- BOOL
- PutBMHD(struct IFFHandle *Handle,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI)
- {
- /* Valid parameters? */
-
- if(X_DPI > 0 && Y_DPI > 0 && Width > 0 && Height > 0)
- {
- BitMapHeader Header;
- UWORD gcd;
-
- /* So we can store neat & small
- * aspect ration values.
- */
-
- gcd = Euclid(X_DPI,Y_DPI);
-
- Header . w = Width;
- Header . h = Height;
- Header . pageWidth = Width;
- Header . pageHeight = Height;
- Header . x = 0;
- Header . y = 0;
- Header . nPlanes = 1;
- Header . masking = 0;
- Header . compression = 1;
- Header . pad1 = 0;
- Header . transparentColor = 0;
- Header . xAspect = X_DPI / gcd;
- Header . yAspect = Y_DPI / gcd;
-
- if(!PushChunk(Handle,0,ID_BMHD,sizeof(Header)))
- {
- if(WriteChunkRecords(Handle,&Header,sizeof(Header),1) == 1)
- {
- if(!PopChunk(Handle))
- return(TRUE);
- }
- }
- }
-
- return(FALSE);
- }
-
- /* SaveBitMap(STRPTR Name,struct BitMap *BitMap,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI):
- *
- * Store a bitmap in an IFF-ILBM file.
- */
-
- BOOL
- SaveBitMap(STRPTR Name,struct BitMap *BitMap,LONG Width,LONG Height,UWORD X_DPI,UWORD Y_DPI)
- {
- struct IFFHandle *Handle;
- BOOL Success = FALSE;
-
- if(Handle = AllocIFF())
- {
- if(Handle -> iff_Stream = Open(Name,MODE_NEWFILE))
- {
- InitIFFasDOS(Handle);
-
- if(!OpenIFF(Handle,IFFF_WRITE))
- {
- if(!PushChunk(Handle,ID_ILBM,ID_FORM,IFFSIZE_UNKNOWN))
- {
- if(PutBMHD(Handle,Width,Height,X_DPI,Y_DPI))
- {
- if(PutANNO(Handle))
- {
- if(PutCMAP(Handle))
- {
- if(PutCAMG(Handle))
- {
- if(PutDPI(Handle,X_DPI,Y_DPI))
- {
- if(PutBODY(Handle,BitMap))
- Success = TRUE;
- }
- }
- }
- }
- }
-
- if(PopChunk(Handle))
- Success = FALSE;
- }
-
- CloseIFF(Handle);
- }
-
- Close(Handle -> iff_Stream);
-
- if(!Success)
- DeleteFile(Name);
- }
-
- FreeIFF(Handle);
- }
-
- return(Success);
- }
-
- /* GetInches(STRPTR Buffer):
- *
- * Turn a parameter string into a number representing
- * a certain number of inches.
- */
-
- float
- GetInches(STRPTR Buffer)
- {
- STATIC struct { STRPTR Unit; float Factor; } Units[7] =
- {
- "pt", 1.0, /* Point */
- "pc", 12.0, /* Pica */
- "in", 72.72, /* Inch */
- "cm", 72.72 / 2.54, /* Centimeter */
- "mm", 727.2 / 2.54, /* Millimeter */
- "dd", 1157.0 / 1238.0, /* Didot point */
- "cc", 1157.0 / 103.0 /* Cicero */
- };
-
- UBYTE Temp[40];
- float Value;
- LONG i;
-
- i = 0;
-
- /* Strip the numeric part. */
-
- while((Buffer[i] >= '0' && Buffer[i] <= '9') || Buffer[i] == '.' || Buffer[i] == '+' || Buffer[i] == '-' || Buffer[i] == 'e')
- {
- Temp[i] = Buffer[i];
-
- i++;
- }
-
- /* Provide null-termination. */
-
- Temp[i] = 0;
-
- /* atof() appears to be broken in ixemul.library 39.45. */
-
- sscanf(Temp,"%f",&Value);
-
- Buffer += i;
-
- /* Which measuring unit? */
-
- for(i = 0 ; i < 7 ; i++)
- {
- /* Return the result in inches. */
-
- if(!Stricmp(Buffer,Units[i] . Unit))
- return(Value * Units[i] . Factor / 72.27);
- }
-
- /* Return the result in inches. */
-
- return(Value / 72.27);
- }
-
- /* DispatchTask():
- *
- * Asynchronous window message dispatcher.
- */
-
- VOID
- DispatchTask()
- {
- struct Task *me;
- gx_device *dev;
-
- /* Set up global data area base register. */
-
- ix_geta4();
-
- /* Who am I? */
-
- me = FindTask(NULL);
-
- /* Wait for wakeup call. */
-
- Wait(SIG_HANDSHAKE);
-
- /* Obtain device pointer. */
-
- dev = me -> tc_UserData;
-
- /* Enable user input. */
-
- if(ModifyIDCMP(xdev -> window,IDCMP_FLAGS))
- {
- ULONG Mask = 1 << xdev -> window -> UserPort -> mp_SigBit,
- Set;
- BOOL Done = FALSE;
-
- /* Fill in the dispatcher entry. */
-
- xdev -> dispatcher = me;
-
- /* Ring back. */
-
- Signal((struct Task *)xdev -> main,SIG_HANDSHAKE);
-
- /* Wait for input... */
-
- do
- {
- Set = Wait(Mask | SIG_KILL);
-
- if(Set & Mask)
- DispatchSuperWindow(dev);
-
- if(Set & SIG_KILL)
- Done = TRUE;
- }
- while(!Done);
-
- /* Disable user input. */
-
- ModifyIDCMP(xdev -> window,NULL);
- }
-
- /* Disable task switching. */
-
- Forbid();
-
- /* Clear the dispatcher entry. */
-
- xdev -> dispatcher = NULL;
-
- /* Signal the main process that we are done. */
-
- Signal((struct Task *)xdev -> main,SIG_HANDSHAKE);
-
- /* Remove ourselves. */
-
- RemTask(NULL);
- }
-
- /* DeleteScrollers(gx_device *dev):
- *
- * Delete the window border scrollers.
- */
-
- VOID
- DeleteScrollers(gx_device *dev)
- {
- if(xdev -> gadget)
- {
- if(xdev -> gadget[HORIZONTAL_SCROLLER])
- DisposeObject(xdev -> gadget[HORIZONTAL_SCROLLER]);
-
- if(xdev -> gadget[VERTICAL_SCROLLER])
- DisposeObject(xdev -> gadget[VERTICAL_SCROLLER]);
-
- if(xdev -> gadget[UP_ARROW])
- DisposeObject(xdev -> gadget[UP_ARROW]);
-
- if(xdev -> gadget[DOWN_ARROW])
- DisposeObject(xdev -> gadget[DOWN_ARROW]);
-
- if(xdev -> gadget[LEFT_ARROW])
- DisposeObject(xdev -> gadget[LEFT_ARROW]);
-
- if(xdev -> gadget[RIGHT_ARROW])
- DisposeObject(xdev -> gadget[RIGHT_ARROW]);
-
- FreeVec(xdev -> gadget);
-
- xdev -> gadget = NULL;
- }
-
- if(xdev -> image)
- {
- if(xdev -> image[UP_IMAGE])
- DisposeObject(xdev -> image[UP_IMAGE]);
-
- if(xdev -> image[DOWN_IMAGE])
- DisposeObject(xdev -> image[DOWN_IMAGE]);
-
- if(xdev -> image[LEFT_IMAGE])
- DisposeObject(xdev -> image[LEFT_IMAGE]);
-
- if(xdev -> image[RIGHT_IMAGE])
- DisposeObject(xdev -> image[RIGHT_IMAGE]);
-
- FreeVec(xdev -> image);
-
- xdev -> image = NULL;
- }
- }
-
- /* CreateScrollers(gx_device *dev,struct Screen *Screen):
- *
- * Create the window border scroller handles.
- */
-
- BOOL
- CreateScrollers(gx_device *dev,struct Screen *Screen)
- {
- BOOL Result = FALSE;
-
- if(xdev -> gadget = (struct Gadget **)AllocVec(sizeof(struct Gadget *) * GADGET_COUNT,MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC))
- {
- if(xdev -> image = (struct Image **)AllocVec(sizeof(struct Image *) * IMAGE_COUNT,MEMF_ANY | MEMF_CLEAR | MEMF_PUBLIC))
- {
- struct DrawInfo *DrawInfo;
-
- if(DrawInfo = GetScreenDrawInfo(Screen))
- {
- LONG SizeWidth,
- SizeHeight;
- UWORD SizeType;
-
- if(Screen -> Flags & SCREENHIRES)
- {
- SizeWidth = 18;
- SizeHeight = 10;
-
- SizeType = SYSISIZE_MEDRES;
- }
- else
- {
- SizeWidth = 13;
- SizeHeight = 11;
-
- SizeType = SYSISIZE_LOWRES;
- }
-
- if(xdev -> image[UP_IMAGE] = (struct Image *)NewObject(NULL,"sysiclass",
- SYSIA_Size, SizeType,
- SYSIA_Which, UPIMAGE,
- SYSIA_DrawInfo, DrawInfo,
- TAG_DONE))
- {
- if(xdev -> image[DOWN_IMAGE] = (struct Image *)NewObject(NULL,"sysiclass",
- SYSIA_Size, SizeType,
- SYSIA_Which, DOWNIMAGE,
- SYSIA_DrawInfo, DrawInfo,
- TAG_DONE))
- {
- if(xdev -> image[LEFT_IMAGE] = (struct Image *)NewObject(NULL,"sysiclass",
- SYSIA_Size, SizeType,
- SYSIA_Which, LEFTIMAGE,
- SYSIA_DrawInfo, DrawInfo,
- TAG_DONE))
- {
- if(xdev -> image[RIGHT_IMAGE] = (struct Image *)NewObject(NULL,"sysiclass",
- SYSIA_Size, SizeType,
- SYSIA_Which, RIGHTIMAGE,
- SYSIA_DrawInfo, DrawInfo,
- TAG_DONE))
- {
- if(xdev -> gadget[VERTICAL_SCROLLER] = NewObject(NULL,"propgclass",
- GA_ID, VERTICAL_SCROLLER,
-
- GA_Top, Screen -> WBorTop + Screen -> Font -> ta_YSize + 2,
- GA_RelHeight, -(Screen -> WBorTop + Screen -> Font -> ta_YSize + 2 + SizeHeight + 1 + 2 * ARROW_HEIGHT),
- GA_Width, SizeWidth - 8,
- GA_RelRight, -(SizeWidth - 5),
-
- GA_GZZGadget, TRUE,
- GA_Immediate, TRUE,
- GA_FollowMouse, TRUE,
- GA_RelVerify, TRUE,
- GA_RightBorder, TRUE,
-
- PGA_Freedom, FREEVERT,
- PGA_NewLook, TRUE,
- PGA_Borderless, TRUE,
-
- PGA_Visible, 1,
- PGA_Total, 1,
- TAG_DONE))
- {
- if(xdev -> gadget[HORIZONTAL_SCROLLER] = NewObject(NULL,"propgclass",
- GA_ID, HORIZONTAL_SCROLLER,
- GA_Previous, xdev -> gadget[VERTICAL_SCROLLER],
-
- GA_Height, SizeHeight - 4,
- GA_RelBottom, -(SizeHeight - 4 + 1),
- GA_Left, 4,
- GA_RelWidth, -(2 + SizeWidth + 4 + 2 * ARROW_WIDTH),
-
- GA_GZZGadget, TRUE,
- GA_Immediate, TRUE,
- GA_FollowMouse, TRUE,
- GA_RelVerify, TRUE,
- GA_BottomBorder,TRUE,
-
- PGA_Freedom, FREEHORIZ,
- PGA_NewLook, TRUE,
- PGA_Borderless, TRUE,
-
- PGA_Visible, 1,
- PGA_Total, 1,
- TAG_DONE))
- {
- STATIC struct TagItem ArrowMappings[] = { GA_ID, GA_ID, TAG_END };
-
- if(xdev -> gadget[UP_ARROW] = NewObject(NULL,"buttongclass",
- GA_ID, UP_ARROW,
- GA_Previous, xdev -> gadget[HORIZONTAL_SCROLLER],
-
- GA_GZZGadget, TRUE,
- GA_Image, xdev -> image[UP_IMAGE],
- GA_RelRight, -(SizeWidth - 1),
- GA_RelBottom, -(SizeHeight - 1 + 2 * ARROW_HEIGHT),
- GA_Height, ARROW_HEIGHT,
- GA_Width, SizeWidth,
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
- GA_RightBorder, TRUE,
-
- ICA_TARGET, ICTARGET_IDCMP,
- ICA_MAP, ArrowMappings,
- TAG_DONE))
- {
- if(xdev -> gadget[DOWN_ARROW] = NewObject(NULL,"buttongclass",
- GA_ID, DOWN_ARROW,
- GA_Previous, xdev -> gadget[UP_ARROW],
-
- GA_GZZGadget, TRUE,
- GA_Image, xdev -> image[DOWN_IMAGE],
- GA_RelRight, -(SizeWidth - 1),
- GA_RelBottom, -(SizeHeight - 1 + ARROW_HEIGHT),
- GA_Height, ARROW_HEIGHT,
- GA_Width, SizeWidth,
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
- GA_RightBorder, TRUE,
-
- ICA_TARGET, ICTARGET_IDCMP,
- ICA_MAP, ArrowMappings,
- TAG_DONE))
- {
- if(xdev -> gadget[LEFT_ARROW] = NewObject(NULL,"buttongclass",
- GA_ID, LEFT_ARROW,
- GA_Previous, xdev -> gadget[DOWN_ARROW],
-
- GA_GZZGadget, TRUE,
- GA_Image, xdev -> image[LEFT_IMAGE],
- GA_RelRight, -(SizeWidth - 1 + 2 * ARROW_WIDTH),
- GA_RelBottom, -(SizeHeight - 1),
- GA_Height, SizeHeight,
- GA_Width, ARROW_WIDTH,
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
- GA_BottomBorder,TRUE,
-
- ICA_TARGET, ICTARGET_IDCMP,
- ICA_MAP, ArrowMappings,
- TAG_DONE))
- {
- if(xdev -> gadget[RIGHT_ARROW] = NewObject(NULL,"buttongclass",
- GA_ID, RIGHT_ARROW,
- GA_Previous, xdev -> gadget[LEFT_ARROW],
-
- GA_GZZGadget, TRUE,
- GA_Image, xdev -> image[RIGHT_IMAGE],
- GA_RelRight, -(SizeWidth - 1 + ARROW_WIDTH),
- GA_RelBottom, -(SizeHeight - 1),
- GA_Height, SizeHeight,
- GA_Width, ARROW_WIDTH,
- GA_Immediate, TRUE,
- GA_RelVerify, TRUE,
- GA_BottomBorder,TRUE,
-
- ICA_TARGET, ICTARGET_IDCMP,
- ICA_MAP, ArrowMappings,
- TAG_DONE))
- Result = TRUE;
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- FreeScreenDrawInfo(Screen,DrawInfo);
- }
- }
- }
-
- return(Result);
- }
-
- /* WindowResize(gx_device *dev):
- *
- * Update the slider sizes and positions after the window
- * was resized.
- */
-
- VOID
- WindowResize(gx_device *dev)
- {
- LONG DeltaX,
- DeltaY,
- Temp;
-
- /* Query the current horizontal slider position. */
-
- if((Temp = LAYERXOFFSET(xdev -> window) + xdev -> window -> GZZWidth) > xdev -> super_width)
- DeltaX = xdev -> super_width - Temp;
- else
- DeltaX = 0;
-
- /* Query the current vertical slider position. */
-
- if((Temp = LAYERYOFFSET(xdev -> window) + xdev -> window -> GZZHeight) > xdev -> super_height)
- DeltaY = xdev -> super_height - Temp;
- else
- DeltaY = 0;
-
- /* Move the currently displayed window area around. */
-
- if(DeltaX || DeltaY)
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,DeltaX,DeltaY);
-
- /* Update the new horizontal slider position and size. */
-
- SetGadgetAttrs(xdev -> gadget[HORIZONTAL_SCROLLER],xdev -> window,NULL,
- PGA_Top, LAYERXOFFSET(xdev -> window),
- PGA_Visible, xdev -> window -> GZZWidth,
- PGA_Total, xdev -> super_width,
- TAG_DONE);
-
- /* Update the new vertical slider position and size. */
-
- SetGadgetAttrs(xdev -> gadget[VERTICAL_SCROLLER],xdev -> window,NULL,
- PGA_Top, LAYERYOFFSET(xdev -> window),
- PGA_Visible, xdev -> window -> GZZHeight,
- PGA_Total, xdev -> super_height,
- TAG_DONE);
- }
-
- /* WindowUpdate(struct Gadget *Gadget,gx_device *dev):
- *
- * Move the currently visible portion of the
- * window according to the current slider
- * position.
- */
-
- VOID
- WindowUpdate(struct Gadget *Gadget,gx_device *dev)
- {
- LONG Storage;
-
- switch(Gadget -> GadgetID)
- {
- case HORIZONTAL_SCROLLER:
-
- if(GetAttr(PGA_Top,Gadget,&Storage))
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,Storage - LAYERXOFFSET(xdev -> window),0);
-
- break;
-
- case VERTICAL_SCROLLER:
-
- if(GetAttr(PGA_Top,Gadget,&Storage))
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,0,Storage - LAYERYOFFSET(xdev -> window));
-
- break;
- }
- }
-
- /* MoveAround(struct Gadget *Gadget,int How,gx_device *dev):
- *
- * Move the currently visible window area according to
- * user input.
- */
-
- VOID
- MoveAround(struct Gadget *Gadget,LONG How,gx_device *dev)
- {
- LONG Storage;
-
- if(GetAttr(PGA_Top,Gadget,&Storage))
- {
- LONG Max;
-
- switch(Gadget -> GadgetID)
- {
- case HORIZONTAL_SCROLLER:
-
- Max = xdev -> super_width - xdev -> window -> GZZWidth;
- break;
-
- case VERTICAL_SCROLLER:
-
- Max = xdev -> super_height - xdev -> window -> GZZHeight;
- break;
- }
-
- switch(How)
- {
- case MOVE_MIN:
-
- Storage = 0;
- break;
-
- case MOVE_MAX:
-
- Storage = Max;
- break;
-
- case MOVE_DOWN:
-
- if(Storage > xdev -> super_height / 100)
- Storage -= xdev -> super_height / 100;
- else
- Storage = 0;
-
- break;
-
- case MOVE_FAR_DOWN:
-
- if(Storage > xdev -> super_height / 10)
- Storage -= xdev -> super_height / 10;
- else
- Storage = 0;
-
- break;
-
- case MOVE_FAR_UP:
-
- if(Storage + xdev -> super_width / 10 < Max)
- Storage += xdev -> super_width / 10;
- else
- Storage = Max;
-
- break;
-
- case MOVE_UP:
-
- if(Storage + xdev -> super_width / 100 < Max)
- Storage += xdev -> super_width / 100;
- else
- Storage = Max;
-
- break;
- }
-
- switch(Gadget -> GadgetID)
- {
- case HORIZONTAL_SCROLLER:
-
- if(LAYERXOFFSET(xdev -> window) != Storage)
- {
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,Storage - LAYERXOFFSET(xdev -> window),0);
-
- SetGadgetAttrs(Gadget,xdev -> window,NULL,
- PGA_Top,Storage,
- TAG_DONE);
- }
-
- break;
-
- case VERTICAL_SCROLLER:
-
- if(LAYERYOFFSET(xdev -> window) != Storage)
- {
- ScrollLayer(NULL,xdev -> window -> RPort -> Layer,0,Storage - LAYERYOFFSET(xdev -> window));
-
- SetGadgetAttrs(Gadget,xdev -> window,NULL,
- PGA_Top,Storage,
- TAG_DONE);
- }
-
- break;
- }
- }
- }
-
- /* DispatchSuperWindow(gx_device *dev):
- *
- * Dispatch user window input.
- */
-
- VOID
- DispatchSuperWindow(gx_device *dev)
- {
- STATIC struct Gadget *CurrentGadget = NULL;
-
- struct IntuiMessage *IntuiMessage;
- ULONG MsgClass,
- MsgCode,
- MsgQualifier;
- struct Gadget *MsgGadget;
-
- while(IntuiMessage = (struct IntuiMessage *)GetMsg(xdev -> window -> UserPort))
- {
- MsgClass = IntuiMessage -> Class;
- MsgCode = IntuiMessage -> Code;
- MsgQualifier = IntuiMessage -> Qualifier;
- MsgGadget = IntuiMessage -> IAddress;
-
- ReplyMsg((struct Message *)IntuiMessage);
-
- switch(MsgClass)
- {
- case IDCMP_VANILLAKEY:
-
- if(MsgCode == '\033' || MsgCode == '\003')
- Signal((struct Task *)xdev -> main,SIG_KILL);
-
- break;
-
- case IDCMP_RAWKEY:
-
- switch(MsgCode)
- {
- case HELP_CODE:
-
- DisplayBeep(xdev -> window -> WScreen);
-
- break;
-
- case CURSORUP:
-
- if(MsgQualifier & IEQUALIFIER_CONTROL)
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_MIN,dev);
- else
- {
- if(MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_FAR_DOWN,dev);
- else
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_DOWN,dev);
- }
-
- break;
-
- case CURSORLEFT:
-
- if(MsgQualifier & IEQUALIFIER_CONTROL)
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_MIN,dev);
- else
- {
- if(MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_FAR_DOWN,dev);
- else
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_DOWN,dev);
- }
-
- break;
-
- case CURSORRIGHT:
-
- if(MsgQualifier & IEQUALIFIER_CONTROL)
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_MAX,dev);
- else
- {
- if(MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_FAR_UP,dev);
- else
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_UP,dev);
- }
-
- break;
-
- case CURSORDOWN:
-
- if(MsgQualifier & IEQUALIFIER_CONTROL)
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_MAX,dev);
- else
- {
- if(MsgQualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_FAR_UP,dev);
- else
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_UP,dev);
- }
-
- break;
-
- default:
-
- break;
- }
-
- break;
-
- case IDCMP_CLOSEWINDOW:
-
- Signal((struct Task *)xdev -> main,SIG_KILL);
-
- break;
-
- case IDCMP_GADGETDOWN:
-
- CurrentGadget = MsgGadget;
-
- WindowUpdate(MsgGadget,dev);
-
- break;
-
- case IDCMP_GADGETUP:
-
- CurrentGadget = NULL;
-
- WindowUpdate(MsgGadget,dev);
-
- break;
-
- case IDCMP_MOUSEMOVE:
-
- if(CurrentGadget)
- WindowUpdate(CurrentGadget,dev);
-
- break;
-
- case IDCMP_IDCMPUPDATE:
-
- switch(GetTagData(GA_ID,0,(struct TagItem *)MsgGadget))
- {
- case UP_ARROW:
-
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_DOWN,dev);
- break;
-
- case DOWN_ARROW:
-
- MoveAround(xdev -> gadget[VERTICAL_SCROLLER],MOVE_UP,dev);
- break;
-
- case LEFT_ARROW:
-
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_DOWN,dev);
- break;
-
- case RIGHT_ARROW:
-
- MoveAround(xdev -> gadget[HORIZONTAL_SCROLLER],MOVE_UP,dev);
- break;
-
- default:
-
- break;
- }
-
- break;
-
- case IDCMP_NEWSIZE:
-
- WindowResize(dev);
-
- break;
-
- default:
-
- break;
- }
- }
- }
-
- /* Simple routine to call the cleanup routine of a device,
- * all devices are smart enough to handle shutdown in
- * case they have not been opened yet.
- */
-
- STATIC void __inline
- close_device(gx_device_amiga *dev)
- {
- (*xdev -> procs -> close_device)((gx_device *)dev);
- }
-
- /* devcleanup():
- *
- * Clean up all devices, free all resources.
- */
-
- void
- devcleanup()
- {
- close_device(&gs_amiga_device);
- close_device(&gs_amiga_low_device);
- close_device(&gs_amiga_high_device);
- close_device(&gs_amiga_super_device);
- close_device(&gs_amiga_a2024_device);
- close_device(&gs_amiga_picassoii_device);
- close_device(&gs_amiga_custom_device);
- close_device(&gs_amiga_printer_device);
- close_device(&gs_amiga_ilbm_device);
- }
-
- /* amiga_set_pen(gx_device *dev,gx_color_index color):
- *
- * Sets the rendering pen and remembers the current
- * settings.
- */
-
- STATIC VOID __inline
- amiga_set_pen(gx_device *dev,gx_color_index color)
- {
- if(xdev -> last_pen != color)
- SetAPen(xdev -> rport,xdev -> last_pen = color);
- }
-
- /* amiga_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue):
- *
- * Map a colour either to the black or the light rendering pen.
- */
-
- gx_color_index
- amiga_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue)
- {
- if((red | green | blue) > gx_max_color_value / 2)
- return(LightPen);
- else
- return(DarkPen);
- }
-
- /* amiga_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3]):
- *
- * Map the light/dark rendering pen to RGB values.
- */
-
- int
- amiga_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3])
- {
- int i;
-
- if(color == LightPen)
- {
- for(i = 0 ; i < 3 ; i++)
- rgb[i] = gx_max_color_value;
- }
- else
- {
- for(i = 0 ; i < 3 ; i++)
- rgb[i] = 0;
- }
-
- return(0);
- }
-
- /* AllocatePens(struct ViewPort *VPort,LONG CubeSize):
- *
- * Allocate shareable viewport pens.
- */
-
- LONG *
- AllocatePens(struct ViewPort *VPort,LONG CubeSize)
- {
- if(GfxBase -> LibNode . lib_Version >= 39)
- {
- LONG Total = CubeSize * CubeSize * CubeSize,*Pens;
-
- if(Pens = (LONG *)AllocVec(sizeof(LONG) * Total,MEMF_ANY))
- {
- LONG i,r,g,b,max = CubeSize - 1;
-
- for(i = 0 ; i < Total ; i++)
- Pens[i] = -1;
-
- i = 0;
-
- for(r = 0 ; r < CubeSize ; r++)
- {
- for(g = 0 ; g < CubeSize ; g++)
- {
- for(b = 0 ; b < CubeSize ; b++)
- {
- if((Pens[i++] = ObtainBestPen(VPort -> ColorMap,SPREAD((255 * r) / max),SPREAD((255 * g) / max),SPREAD((255 * b) / max),
- OBP_FailIfBad, TRUE,
- OBP_Precision, PRECISION_IMAGE,
- TAG_DONE)) == -1)
- {
- FreeVec(Pens);
-
- return(NULL);
- }
- }
- }
- }
-
- return(Pens);
- }
- }
-
- return(NULL);
- }
-
- /* amiga_open_default(gx_device *dev):
- *
- * Open the default device, i.e. a window on the Workbench screen.
- */
-
- int
- amiga_open_default(gx_device *dev)
- {
- struct Screen *DefaultScreen;
-
- /* Get a lock on the default public screen. */
-
- if(DefaultScreen = LockPubScreen(NULL))
- {
- struct DisplayInfo DisplayInfo;
- ULONG Mode;
-
- /* Get the default public screen display mode. */
-
- Mode = GetVPModeID(&DefaultScreen -> ViewPort);
-
- /* Inquire display mode information. */
-
- if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,Mode))
- {
- LONG ScreenWidth,
- ScreenHeight;
- LONG i;
- float Width,
- Height;
- LONG Depth;
-
- if(GfxBase -> LibNode . lib_Version >= 39)
- Depth = GetBitMapAttr(DefaultScreen -> RastPort . BitMap,BMA_DEPTH);
- else
- Depth = DefaultScreen -> RastPort . BitMap -> Depth;
-
- /* Determine screen view dimensions. */
-
- if(DefaultScreen -> ViewPort . ColorMap -> cm_vpe)
- {
- struct ViewPortExtra *Extra = DefaultScreen -> ViewPort . ColorMap -> cm_vpe;
-
- ScreenWidth = Extra -> DisplayClip . MaxX - Extra -> DisplayClip . MinX + 1;
- ScreenHeight = Extra -> DisplayClip . MaxY - Extra -> DisplayClip . MinY + 1;
- }
- else
- {
- struct ViewPortExtra *Extra;
-
- if(Extra = (struct ViewPortExtra *)GfxLookUp(&DefaultScreen -> ViewPort))
- {
- ScreenWidth = Extra -> DisplayClip . MaxX - Extra -> DisplayClip . MinX + 1;
- ScreenHeight = Extra -> DisplayClip . MaxY - Extra -> DisplayClip . MinY + 1;
- }
- else
- {
- ScreenWidth = DefaultScreen -> Width;
- ScreenHeight = DefaultScreen -> Height;
- }
- }
-
- /* Use the best guess, we will take the standard
- * low resolution x-dpi value and scale it by
- * the pixel speed.
- */
-
- if(DisplayInfo . PixelSpeed)
- {
- xdev -> x_pixels_per_inch = (35.0 * 140.0) / (float)DisplayInfo . PixelSpeed;
- xdev -> y_pixels_per_inch = (xdev -> x_pixels_per_inch * (float)DisplayInfo . Resolution . x) / (float)DisplayInfo . Resolution . y;
- }
- else
- {
- xdev -> x_pixels_per_inch = 72.27;
- xdev -> y_pixels_per_inch = 72.27;
- }
-
- if(xdev -> width > 0 && xdev -> height > 0)
- {
- xdev -> super_width = xdev -> width;
- xdev -> super_height = xdev -> height;
- }
- else
- {
- if(xdev -> page_width > 0.0)
- xdev -> super_width = (LONG)(xdev -> page_width * xdev -> x_pixels_per_inch);
- else
- xdev -> super_width = 640;
-
- if(xdev -> page_height > 0.0)
- xdev -> super_height = (LONG)(xdev -> page_height * xdev -> y_pixels_per_inch);
- else
- xdev -> super_height = 512;
- }
-
- /* Allocate a bitmap ready to be used for
- * rendering.
- */
-
- if(xdev -> super_bitmap = CreateBitMap(xdev -> super_width,xdev -> super_height,Depth,BMF_DISPLAYABLE,DefaultScreen -> RastPort . BitMap,FALSE))
- {
- /* Clear the bitplanes. */
-
- BltBitMap(xdev -> super_bitmap,0,0,xdev -> super_bitmap,0,0,xdev -> super_width,xdev -> super_height,0x00,(1 << xdev -> super_bitmap -> Depth) - 1,NULL);
-
- /* Create the scroller handles. */
-
- if(CreateScrollers(dev,DefaultScreen))
- {
- struct IBox ZoomBox;
-
- /* Set up the window alternate
- * position.
- */
-
- ZoomBox . Left = 0;
- ZoomBox . Top = DefaultScreen -> BarHeight + 1;
- ZoomBox . Width = ScreenWidth;
- ZoomBox . Height = ScreenHeight - ZoomBox . Top;
-
- /* Eventually, open the display window. */
-
- if(xdev -> window = OpenWindowTags(NULL,
- WA_InnerWidth, MIN(DefaultScreen -> Width / 2,xdev -> super_width),
- WA_InnerHeight, MIN(DefaultScreen -> Height / 2,xdev -> super_height),
- WA_CloseGadget, TRUE,
- WA_DepthGadget, TRUE,
- WA_SizeGadget, TRUE,
- WA_SizeBRight, TRUE,
- WA_SizeBBottom, TRUE,
- WA_Zoom, &ZoomBox,
- WA_DragBar, TRUE,
- WA_NoCareRefresh, TRUE,
- WA_GimmeZeroZero, TRUE,
- WA_RMBTrap, TRUE,
- WA_SuperBitMap, xdev -> super_bitmap,
- WA_Gadgets, xdev -> gadget[VERTICAL_SCROLLER],
- WA_CustomScreen, DefaultScreen,
- WA_Title, "Ghostscript Amiga output window",
- TAG_DONE))
- {
- if(xdev -> temp_rport = CreateTempRPort(xdev -> window -> RPort))
- {
- if(xdev -> temp_array = (UBYTE *)AllocVec((xdev -> window -> WScreen -> Width + 15) & ~15,MEMF_ANY))
- {
- struct Task *Task;
-
- /* Bring the window dispatcher task
- * to life...
- */
-
- if(Task = (struct Task *)CreateTask("Ghostscript window dispatcher",5,DispatchTask,8192))
- {
- const sigset_t trapped = sigmask(SIGINT);
-
- /* Cheap... */
-
- Task -> tc_UserData = dev;
-
- /* Who's calling? */
-
- xdev -> main = (struct Process *)FindTask(NULL);
-
- /* Don't let anybody interrupt us! */
-
- sigprocmask(SIG_BLOCK,&trapped,NULL);
-
- Forbid();
-
- /* Wake it up. */
-
- Signal(Task,SIG_HANDSHAKE);
-
- /* Clear the handshake bit. */
-
- SetSignal(0,SIG_HANDSHAKE);
-
- /* Wait for the report. */
-
- Wait(SIG_HANDSHAKE);
-
- Permit();
-
- /* Get the result. */
-
- Task = xdev -> dispatcher;
-
- /* Unblock signals. */
-
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
- }
-
- /* Did we succeed in creating
- * the dispatcher task?
- */
-
- if(Task)
- {
- UWORD MaxValue = 0,
- MinValue = 15000,
- Value,
- R,G,B;
-
- /* Set the window limits. */
-
- WindowLimits(xdev -> window,xdev -> window -> BorderLeft + MINIMUM_WIDTH + xdev -> window -> BorderRight,xdev -> window -> BorderTop + MINIMUM_HEIGHT + xdev -> window -> BorderBottom,xdev -> window -> BorderLeft + xdev -> super_width + xdev -> window -> BorderRight,xdev -> window -> BorderTop + xdev -> super_height + xdev -> window -> BorderBottom);
-
- /* Update the sliders. */
-
- WindowResize(dev);
-
- /* Look for the darkest and the lightest screen colours. */
-
- for(i = 0 ; i < MIN(xdev -> window -> WScreen -> ViewPort . ColorMap -> Count,(1 << Depth)) ; i++)
- {
- Value = GetRGB4(xdev -> window -> WScreen -> ViewPort . ColorMap,i);
-
- R = (Value >> 8) & 0xF;
- G = (Value >> 4) & 0xF;
- B = Value & 0xF;
-
- /* Luminance conversion included */
-
- Value = R * 299 + G * 588 + B * 113;
-
- if(Value > MaxValue)
- {
- MaxValue = Value;
-
- LightPen = i;
- }
-
- if(Value < MinValue)
- {
- MinValue = Value;
-
- DarkPen = i;
- }
- }
-
- /* Fill in the rest. */
-
- xdev -> width = xdev -> super_width;
- xdev -> height = xdev -> super_height;
- xdev -> rport = xdev -> window -> RPort;
-
- /* Does the display support
- * at least eight colours?
- */
-
- if(Depth >= 3)
- {
- LONG cube_size,max;
-
- /* Set up a fitting colour cube. */
-
- for(cube_size = 6 ; cube_size >= 2 ; cube_size--)
- {
- if((max = cube_size * cube_size * cube_size) <= 1 << Depth)
- break;
- }
-
- /* Got enough colours? */
-
- if(cube_size != 1)
- {
- LONG *Pens;
-
- /* Try to grab the cube colours,
- * making a colour display.
- */
-
- if(Pens = AllocatePens(&xdev -> window -> WScreen -> ViewPort,cube_size))
- set_colour_device((gx_device_amiga *)dev,cube_size,Pens);
- }
- }
-
- SetBPen(xdev -> rport,0);
- SetDrMd(xdev -> rport,JAM2);
-
- amiga_set_pen(dev,DarkPen);
-
- UnlockPubScreen(NULL,DefaultScreen);
-
- return(0);
- }
- else
- perror("Ghostscript: failed to create dispatcher task");
- }
- else
- perror("Ghostscript: failed to create temporary line buffer.");
- }
- else
- perror("Ghostscript: failed to create temporary raster port");
- }
- else
- perror("Ghostscript: failed to open window");
- }
- else
- perror("Ghostscript: failed to allocate scrollers");
- }
- else
- perror("Ghostscript: failed to allocate bitmap");
- }
- else
- perror("Ghostscript: failed to get display mode information");
-
- UnlockPubScreen(NULL,DefaultScreen);
- }
- else
- perror("Ghostscript: failed to lock default public screen");
-
- return(-1);
- }
-
- /* amiga_open_low(gx_device *dev):
- *
- * Open the low resolution device.
- */
-
- int
- amiga_open_low(gx_device *dev)
- {
- return(amiga_open(dev,LORES_KEY));
- }
-
- /* amiga_open_high(gx_device *dev):
- *
- * Open the high resolution device.
- */
-
- int
- amiga_open_high(gx_device *dev)
- {
- return(amiga_open(dev,HIRESLACE_KEY));
- }
-
- /* amiga_open_super(gx_device *dev):
- *
- * Open the super high resolution device.
- */
-
- int
- amiga_open_super(gx_device *dev)
- {
- /* Fall back to the default if not available. */
-
- if(ModeNotAvailable(SUPERLACE_KEY))
- return(amiga_open_high(dev));
- else
- return(amiga_open(dev,SUPERLACE_KEY));
- }
-
- /* amiga_open_a2024(gx_device *dev):
- *
- * Open the A2024 device.
- */
-
- int
- amiga_open_a2024(gx_device *dev)
- {
- /* Fall back to the default if not available. */
-
- if(ModeNotAvailable(A2024TENHERTZ_KEY))
- return(amiga_open_super(dev));
- else
- return(amiga_open(dev,A2024TENHERTZ_KEY));
- }
-
- /* amiga_open_picassoii(gx_device *dev):
- *
- * Open the Picasso II device.
- */
-
- int
- amiga_open_picassoii(gx_device *dev)
- {
- /* Fall back to the default if not available. */
-
- if(ModeNotAvailable(0x40020002))
- return(amiga_open_super(dev));
- else
- return(amiga_open(dev,0x40020002));
- }
-
- int
- amiga_open_custom(gx_device *dev)
- {
- UBYTE Buffer[256];
- ULONG ScreenID = INVALID_ID;
- BOOL DontTouch = FALSE;
-
- /* First step: check for an environment variable to give
- * the name of the display mode to use.
- */
-
- if(GetVar("GSCUSTOMMODE",Buffer,256,NULL) != -1)
- {
- UBYTE PatternBuffer[516];
-
- /* Set up the search pattern. */
-
- if(ParsePatternNoCase(Buffer,PatternBuffer,516) >= 0)
- {
- ULONG CurrentID = INVALID_ID,ID;
-
- /* Scan the entire list. */
-
- while((CurrentID = NextDisplayInfo(CurrentID)) != INVALID_ID)
- {
- /* Valid mode? */
-
- if(!ModeNotAvailable(CurrentID))
- {
- struct NameInfo NameInfo;
-
- /* Get the name information. */
-
- if(GetDisplayInfoData(NULL,&NameInfo,sizeof(struct NameInfo),DTAG_NAME,CurrentID))
- {
- /* Does the mode name match the pattern given? */
-
- if(MatchPatternNoCase(PatternBuffer,NameInfo . Name))
- {
- ScreenID = CurrentID;
-
- /* Don't overwrite the variable contents. */
-
- DontTouch = TRUE;
-
- break;
- }
- }
- }
- }
- }
- }
-
- if(ScreenID == INVALID_ID && AslBase)
- {
- struct ScreenModeRequester *ScreenModeRequester;
-
- if(ScreenModeRequester = (struct ScreenModeRequester *)AllocAslRequestTags(ASL_ScreenModeRequest,TAG_DONE))
- {
- if(AslRequestTags(ScreenModeRequester,
- ASLSM_TitleText, "Select GhostScript screen display mode",
- ASLSM_MinDepth, 1,
- ASLSM_MaxDepth, 8,
- TAG_DONE))
- ScreenID = ScreenModeRequester -> sm_DisplayID;
-
- FreeAslRequest(ScreenModeRequester);
- }
- }
-
- /* Fall back to the default if not available. */
-
- if(ModeNotAvailable(ScreenID))
- return(amiga_open_default(dev));
- else
- {
- int result = amiga_open(dev,ScreenID);
-
- /* If successful store the name of the
- * screen mode selected.
- */
-
- if(!result && !DontTouch)
- {
- struct NameInfo NameInfo;
-
- if(GetDisplayInfoData(NULL,&NameInfo,sizeof(struct NameInfo),DTAG_NAME,ScreenID))
- SetVar("GSCUSTOMMODE",NameInfo . Name,-1,NULL);
- }
-
- return(result);
- }
- }
-
- /* amiga_open_printer(gx_device *dev):
- *
- * Open the printer device.
- */
-
- int
- amiga_open_printer(gx_device *dev)
- {
- if(xdev -> port = CreateMsgPort())
- {
- if(xdev -> printer = (struct IODRPReq *)CreateIORequest(xdev -> port,sizeof(struct IODRPReq)))
- {
- if(!OpenDevice("printer.device",0,(struct IORequest *)xdev -> printer,0))
- {
- if(xdev -> rport = (struct RastPort *)AllocVec(sizeof(struct RastPort),MEMF_ANY))
- {
- const sigset_t trapped = sigmask(SIGINT);
- struct BitMap DummyBitMap;
- UWORD DummyLine[12];
-
- InitRastPort(xdev -> rport);
-
- /* Cook up a dummy bitmap to keep
- * `smart' drivers from complaining.
- */
-
- InitBitMap(&DummyBitMap,12,16,16);
-
- DummyBitMap . Planes[0] = (PLANEPTR)&DummyLine;
-
- xdev -> rport -> BitMap = &DummyBitMap;
-
- /* Query page size requirements. */
-
- xdev -> printer -> io_Command = PRD_DUMPRPORT;
- xdev -> printer -> io_RastPort = xdev -> rport;
- xdev -> printer -> io_SrcWidth = 16;
- xdev -> printer -> io_SrcHeight = 16;
- xdev -> printer -> io_Modes = LORES_KEY;
-
- xdev -> printer -> io_Special |= SPECIAL_FULLCOLS | SPECIAL_FULLROWS | SPECIAL_NOPRINT;
-
- /* Don't let them stop us now! */
-
- sigprocmask(SIG_BLOCK,&trapped,NULL);
-
- /* Ask for it... */
-
- if(!DoIO((struct IORequest *)xdev -> printer))
- {
- struct PrinterExtendedData *PED;
- struct PrinterData *PD;
- struct Preferences *Prefs;
- LONG Depth,
- NumColours,
- CubeSize;
- LONG PageWidth,
- PageHeight;
-
- /* Unblock ^C signal. */
-
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
-
- xdev -> printer -> io_Special &= ~(SPECIAL_FULLCOLS | SPECIAL_FULLROWS | SPECIAL_NOPRINT);
-
- /* Get the printer internal data. */
-
- PD = (struct PrinterData *)xdev -> printer -> io_Device;
- PED = &PD -> pd_SegmentData -> ps_PED;
- Prefs = &PD -> pd_Preferences;
-
- /* Calculate the printer page size. */
-
- PageWidth = PED -> ped_XDotsInch * (Prefs -> PrintRightMargin - Prefs -> PrintLeftMargin + 1);
- PageHeight = PED -> ped_YDotsInch * Prefs -> PaperLength;
-
- switch(Prefs -> PrintPitch)
- {
- case PICA:
-
- PageWidth /= 10;
- break;
-
- case ELITE:
-
- PageWidth /= 12;
- break;
-
- case FINE:
-
- PageWidth /= 15;
- break;
- }
-
- switch(Prefs -> PrintSpacing)
- {
- case SIX_LPI:
-
- PageHeight /= 6;
- break;
-
- case EIGHT_LPI:
-
- PageHeight /= 8;
- break;
- }
-
- if(PageWidth > PED -> ped_MaxXDots)
- PageWidth = PED -> ped_MaxXDots;
-
- if(PageHeight > PED -> ped_MaxYDots && PED -> ped_MaxYDots)
- PageHeight = PED -> ped_MaxYDots;
-
- /* Set up the default colour values. */
-
- if(Prefs -> PrintShade == SHADE_BW)
- {
- Depth = 1;
- NumColours = 2;
- CubeSize = 0;
- }
- else
- {
- Depth = 12;
- NumColours = 4096;
- CubeSize = 16;
- }
-
- /* Get the page size */
-
- if(xdev -> width > 0 && xdev -> height > 0)
- {
- if(PageWidth < xdev -> width)
- xdev -> width = PageWidth;
-
- if(PageHeight < xdev -> height)
- xdev -> height = PageHeight;
- }
- else
- {
- xdev -> width = PageWidth;
- xdev -> height = PageHeight;
- }
-
- /* Get the DPI values */
-
- xdev -> x_pixels_per_inch = (float)PED -> ped_XDotsInch;
- xdev -> y_pixels_per_inch = (float)PED -> ped_YDotsInch;
-
- /* Try to allocate a suitable bitmap.
- * If an allocation fails, rescale the
- * colour cube and bitmap depth and
- * retry. Minimum are eight colours.
- */
-
- do
- {
- /* Try to allocate the raster... */
-
- if(!(xdev -> bitmap = CreateBitMap(xdev -> width,xdev -> height,Depth,NULL,NULL,TRUE)))
- {
- /* Any chance to rescale the cube? */
-
- if(Depth < 2)
- break;
- else
- {
- /* One plane less... */
-
- Depth--;
-
- /* Rescale the cube. */
-
- while(CubeSize >= 2)
- {
- if((NumColours = CubeSize * CubeSize * CubeSize) <= (1 << Depth))
- break;
- else
- CubeSize--;
- }
-
- /* Less than eight colours? */
-
- if(CubeSize < 2)
- break;
- }
- }
- }
- while(!xdev -> bitmap);
-
- /* Got the bitmap? */
-
- if(xdev -> bitmap)
- {
- /* Allocate a suitable colour map. */
-
- if(xdev -> colormap = GetColorMap(NumColours))
- {
- /* Black & white only? */
-
- if(NumColours == 2)
- {
- SetRGB4CM(xdev -> colormap,0,0x0,0x0,0x0);
- SetRGB4CM(xdev -> colormap,1,0xF,0xF,0xF);
- }
- else
- {
- LONG i = 0,r,g,b,max = CubeSize - 1;
-
- /* Fill in the colour cube. */
-
- for(r = 0 ; r < CubeSize ; r++)
- {
- for(g = 0 ; g < CubeSize ; g++)
- {
- for(b = 0 ; b < CubeSize ; b++)
- SetRGB4CM(xdev -> colormap,i++,(15 * r) / max,(15 * g) / max,(15 * b) / max);
- }
- }
-
- set_colour_printer_device((gx_device_amiga *)dev,CubeSize);
- }
-
- xdev -> printer -> io_ColorMap = xdev -> colormap;
- xdev -> rport -> BitMap = xdev -> bitmap;
-
- return(0);
- }
- else
- perror("Ghostscript: failed to allocate colour map");
- }
- else
- {
- char buffer[256];
-
- sprintf(buffer,"Ghostscript: failed to allocate raster (wanted %ld, largest %ld)",(xdev -> width + 15) / 8 * xdev -> height * Depth,AvailMem(MEMF_ANY | MEMF_LARGEST));
-
- perror(buffer);
- }
- }
- else
- {
- char buffer[256];
-
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
-
- sprintf(buffer,"Ghostscript: failed to query printer page size (error code #%ld)",xdev -> printer -> io_Error);
-
- perror(buffer);
- }
- }
- else
- perror("Ghostscript: failed to allocate raster port");
- }
- else
- {
- char buffer[256];
-
- sprintf(buffer,"Ghostscript: failed to open printer.device (error code #%ld)",xdev -> printer -> io_Error);
-
- perror(buffer);
- }
- }
- else
- perror("Ghostscript: failed to allocate device driver");
- }
- else
- perror("Ghostscript: failed to create io port");
-
- return(-1);
- }
-
- /* amiga_output_page_printer(gx_device *dev,int,int):
- *
- * Send a bitmap to the printer.
- */
-
- int
- amiga_output_page_printer(gx_device *dev,int num_copies,int flush)
- {
- const sigset_t trapped = sigmask(SIGINT);
- int result,i;
- ULONG Signals;
-
- xdev -> printer -> io_Command = PRD_DUMPRPORT;
- xdev -> printer -> io_SrcWidth = xdev -> width;
- xdev -> printer -> io_SrcHeight = xdev -> height;
- xdev -> printer -> io_DestCols = xdev -> width;
- xdev -> printer -> io_DestRows = xdev -> height;
-
- /* We cannot possibly allow being interrupted in the middle
- * of a raster dump!
- */
-
- sigprocmask(SIG_BLOCK,&trapped,NULL);
-
- for(i = 0 ; i < num_copies ; i++)
- {
- SetSignal(0,SIGBREAKF_CTRL_C | (1L << xdev -> port -> mp_SigBit));
-
- SendIO((struct IORequest *)xdev -> printer);
-
- Signals = Wait(SIGBREAKF_CTRL_C | (1L << xdev -> port -> mp_SigBit));
-
- if(Signals & SIGBREAKF_CTRL_C)
- {
- char buffer[256];
-
- if(!CheckIO((struct IORequest *)xdev -> printer))
- AbortIO((struct IORequest *)xdev -> printer);
-
- WaitIO((struct IORequest *)xdev -> printer);
-
- sprintf(buffer,"Ghostscript: printing aborted");
-
- perror(buffer);
-
- result = -1;
-
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
-
- break;
- }
-
- if(Signals & (1L << xdev -> port -> mp_SigBit))
- {
- if(WaitIO((struct IORequest *)xdev -> printer))
- {
- char buffer[256];
-
- sprintf(buffer,"Ghostscript: failed to print raster (error code #%ld)",xdev -> printer -> io_Error);
-
- perror(buffer);
-
- result = -1;
-
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
-
- break;
- }
- else
- result = 0;
- }
- }
-
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
-
- return(result);
- }
-
- /* amiga_close_printer(gx_device *dev):
- *
- * Close the printer driver.
- */
-
- int
- amiga_close_printer(gx_device *dev)
- {
- if(xdev -> bitmap)
- {
- DeleteBitMap(xdev -> bitmap,TRUE);
-
- xdev -> bitmap = NULL;
- }
-
- if(xdev -> rport)
- {
- FreeVec(xdev -> rport);
-
- xdev -> rport = NULL;
- }
-
- if(xdev -> colormap)
- {
- FreeColorMap(xdev -> colormap);
-
- xdev -> colormap = NULL;
- }
-
- if(xdev -> printer)
- {
- if(xdev -> printer -> io_Device)
- CloseDevice((struct IORequest *)xdev -> printer);
-
- DeleteIORequest(xdev -> printer);
-
- xdev -> printer = NULL;
- }
-
- if(xdev -> port)
- {
- DeleteMsgPort(xdev -> port);
-
- xdev -> port = NULL;
- }
-
- xdev -> width = xdev -> height = 0;
- /* xdev -> x_pixels_per_inch = x_pixels_per_inch = 72.72;*/
-
- return(0);
- }
-
- /* amiga_get_bits(gx_device *dev,int y,byte *str,byte **actual_data):
- *
- * Read the raster bits into a buffer.
- */
-
- int
- amiga_get_bits(gx_device *dev,int y,byte *str,byte **actual_data)
- {
- if(y < 0 || y > xdev -> height)
- return(-1);
- else
- {
- if(actual_data)
- *actual_data = (byte *)(xdev -> bitmap -> Planes[0] + xdev -> bitmap -> BytesPerRow * y);
- else
- memcpy(str,xdev -> bitmap -> Planes[0] + xdev -> bitmap -> BytesPerRow * y,xdev -> bitmap -> BytesPerRow);
-
- return(0);
- }
- }
-
- /* amiga_open(gx_device *dev,ULONG Mode):
- *
- * Open a custom screen.
- */
-
- int
- amiga_open(gx_device *dev,ULONG Mode)
- {
- struct DisplayInfo DisplayInfo;
- struct DimensionInfo DimensionInfo;
-
- /* Get the display dimensions. */
-
- if(GetDisplayInfoData(NULL,(APTR)&DisplayInfo,sizeof(struct DisplayInfo),DTAG_DISP,Mode) && GetDisplayInfoData(NULL,(APTR)&DimensionInfo,sizeof(struct DimensionInfo),DTAG_DIMS,Mode))
- {
- /* Two shades only, black & white */
-
- STATIC struct ColorSpec Colours[] =
- {
- 0, 0x0000, 0x0000, 0x0000,
- 1, 0xFFFF, 0xFFFF, 0xFFFF,
-
- -1
- };
-
- float Width,
- Height;
- LONG i,cube_size,max;
- LONG ScreenWidth,
- ScreenHeight,
- ScreenDepth;
-
- /* Start up with a maximum depth display. */
-
- ScreenDepth = DimensionInfo . MaxDepth;
-
- /* Check to see whether we will be able to
- * build a colour display or not.
- */
-
- for(cube_size = 6 ; cube_size >= 2 ; cube_size--)
- {
- if((max = cube_size * cube_size * cube_size) <= 1 << ScreenDepth)
- break;
- }
-
- /* Got enough colours? */
-
- if(cube_size != 1)
- set_colour_device((gx_device_amiga *)dev,cube_size,NULL);
- else
- {
- ScreenDepth = 1;
-
- set_mono_device((gx_device_amiga *)dev);
- }
-
- if(xdev -> width > 0 && xdev -> height > 0)
- {
- Width = xdev -> width;
- Height = xdev -> height;
- }
- else
- {
- if(xdev -> page_width > 0.0)
- Width = xdev -> page_width;
- else
- Width = 0.0;
-
- if(xdev -> page_height > 0.0)
- Height = xdev -> page_height;
- else
- Height = 0.0;
- }
-
- /* Use the best guess, we will take the standard
- * low resolution x-dpi value and scale it by
- * the pixel speed.
- */
-
- if(DisplayInfo . PixelSpeed)
- {
- xdev -> x_pixels_per_inch = (35.0 * 140.0) / (float)DisplayInfo . PixelSpeed;
- xdev -> y_pixels_per_inch = (xdev -> x_pixels_per_inch * (float)DisplayInfo . Resolution . x) / (float)DisplayInfo . Resolution . y;
- }
- else
- {
- xdev -> x_pixels_per_inch = 72.27;
- xdev -> y_pixels_per_inch = 72.27;
- }
-
- if(Width > 0.0)
- ScreenWidth = (LONG)(Width * xdev -> x_pixels_per_inch);
- else
- ScreenWidth = 0;
-
- if(Height > 0.0)
- ScreenHeight = (LONG)(Height * xdev -> y_pixels_per_inch);
- else
- ScreenHeight = 0;
-
- if(ScreenWidth < DimensionInfo . MinRasterWidth || ScreenWidth > DimensionInfo . MaxRasterWidth)
- ScreenWidth = 0;
-
- if(ScreenHeight < DimensionInfo . MinRasterHeight || ScreenHeight > DimensionInfo . MaxRasterHeight)
- ScreenHeight = 0;
-
- /* Try to open a custom screen; if this fails, try to
- * rescale the colour cube and retry.
- */
-
- do
- {
- if(!(xdev -> screen = OpenScreenTags(NULL,
- SA_Depth, ScreenDepth,
- SA_Overscan, OSCAN_TEXT,
- SA_Quiet, TRUE,
- SA_Behind, TRUE,
- SA_DisplayID, Mode,
- SA_Colors, Colours,
- SA_AutoScroll, TRUE,
- SA_ShowTitle, FALSE,
- SA_Title, "Ghostscript Amiga output screen",
-
- ScreenWidth > 0 ? SA_Width : TAG_IGNORE, ScreenWidth,
- ScreenHeight > 0 ? SA_Height : TAG_IGNORE, ScreenHeight,
- TAG_DONE)))
- {
- if(ScreenDepth < 2)
- break;
- else
- {
- ScreenDepth--;
-
- /* Check to see whether we will be able to
- * build a colour display or not.
- */
-
- while(cube_size >= 2)
- {
- if((max = cube_size * cube_size * cube_size) <= 1 << ScreenDepth)
- break;
- else
- cube_size--;
- }
-
- /* Got enough colours? */
-
- if(cube_size == 1 || ScreenDepth == 1)
- {
- /* Obviously not. */
-
- ScreenDepth = 1;
-
- set_mono_device((gx_device_amiga *)dev);
- }
- }
- }
- }
- while(!xdev -> screen);
-
- /* Did we succeed in opening the screen? */
-
- if(xdev -> screen)
- {
- if(xdev -> window = OpenWindowTags(NULL,
- WA_Left, 0,
- WA_Top, 0,
- WA_Width, xdev -> screen -> Width,
- WA_Height, xdev -> screen -> Height,
- WA_Backdrop, TRUE,
- WA_RMBTrap, TRUE,
- WA_Borderless, TRUE,
- WA_CustomScreen,xdev -> screen,
- TAG_DONE))
- {
- xdev -> rport = xdev -> window -> RPort;
- xdev -> width = xdev -> screen -> Width;
- xdev -> height = xdev -> screen -> Height;
- }
- else
- {
- xdev -> rport = &xdev -> screen -> RastPort;
- xdev -> width = xdev -> screen -> Width;
- xdev -> height = xdev -> screen -> Height;
- }
-
- /* Establish defaults. */
-
- DarkPen = 0;
- LightPen = 1;
-
- SetBPen(xdev -> rport,0);
- SetDrMd(xdev -> rport,JAM2);
-
- /* Create the temporary drawing area. */
-
- if(xdev -> temp_rport = CreateTempRPort(xdev -> rport))
- {
- if(xdev -> temp_array = (UBYTE *)AllocVec((xdev -> screen -> Width + 15) & ~15,MEMF_ANY))
- {
- /* Colour output enabled? */
-
- if(xdev -> cube_size > 0)
- {
- LONG r,g,b,max = xdev -> cube_size - 1;
-
- i = 0;
-
- /* Build a suitable colour map. */
-
- if(GfxBase -> LibNode . lib_Version >= 39)
- {
- for(r = 0 ; r < xdev -> cube_size ; r++)
- {
- for(g = 0 ; g < xdev -> cube_size ; g++)
- {
- for(b = 0 ; b < xdev -> cube_size ; b++)
- SetRGB32(&xdev -> screen -> ViewPort,i++,SPREAD((255 * r) / max),SPREAD((255 * g) / max),SPREAD((255 * b) / max));
- }
- }
- }
- else
- {
- for(r = 0 ; r < xdev -> cube_size ; r++)
- {
- for(g = 0 ; g < xdev -> cube_size ; g++)
- {
- for(b = 0 ; b < xdev -> cube_size ; b++)
- SetRGB4(&xdev -> screen -> ViewPort,i++,(15 * r) / max,(15 * g) / max,(15 * b) / max);
- }
- }
- }
- }
- }
- else
- {
- perror("Ghostscript: failed to allocate temporary line");
-
- return(-1);
- }
- }
- else
- {
- perror("Ghostscript: failed to allocate temporary raster");
-
- return(-1);
- }
-
- amiga_set_pen(dev,DarkPen);
-
- return(0);
- }
- else
- perror("Ghostscript: failed to open screen");
- }
- else
- perror("Ghostscript: failed to get display mode information");
-
- return(-1);
- }
-
- /* amiga_output_page(gx_device *dev,int,int):
- *
- * Page is not `buffered', just bring screen/window
- * to the front.
- */
-
- int
- amiga_output_page(gx_device *dev,int num_copies,int flush)
- {
- if(xdev -> screen)
- ScreenToFront(xdev -> screen);
- else
- {
- if(xdev -> window)
- WindowToFront(xdev -> window);
- }
-
- return(0);
- }
-
- /* amiga_close(gx_device *dev):
- *
- * Close the screen and free associated resources.
- */
-
- int
- amiga_close(gx_device *dev)
- {
- if(xdev -> dispatcher)
- {
- const sigset_t trapped = sigmask(SIGINT);
-
- sigprocmask(SIG_BLOCK,&trapped,NULL);
-
- Forbid();
-
- Signal(xdev -> dispatcher,SIG_KILL);
-
- SetSignal(0,SIG_HANDSHAKE);
-
- Wait(SIG_HANDSHAKE);
-
- Permit();
-
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
- }
-
- if(xdev -> temp_array)
- {
- FreeVec(xdev -> temp_array);
-
- xdev -> temp_array = NULL;
- }
-
- if(xdev -> pens)
- {
- LONG i;
-
- for(i = 0 ; i < xdev -> cube_size * xdev -> cube_size * xdev -> cube_size ; i++)
- {
- if(xdev -> pens[i] != -1)
- ReleasePen(xdev -> window -> WScreen -> ViewPort . ColorMap,xdev -> pens[i]);
- }
-
- FreeVec(xdev -> pens);
-
- xdev -> pens = NULL;
- }
-
- if(xdev -> temp_rport)
- {
- DeleteTempRPort(xdev -> temp_rport);
-
- xdev -> temp_rport = NULL;
- }
-
- if(xdev -> window)
- {
- CloseWindow(xdev -> window);
-
- xdev -> window = NULL;
- }
-
- DeleteScrollers(dev);
-
- if(xdev -> super_bitmap)
- {
- DeleteBitMap(xdev -> super_bitmap,FALSE);
-
- xdev -> super_bitmap = NULL;
- }
-
- if(xdev -> screen)
- {
- CloseScreen(xdev -> screen);
-
- xdev -> screen = NULL;
- }
-
- xdev -> width = xdev -> height = 0;
- /* xdev -> x_pixels_per_inch = x_pixels_per_inch = 72.72;*/
-
- return(0);
- }
-
- /* amiga_fill_rectangle(gx_device *dev,int x,int y,int w,int h,gx_color_index color):
- *
- * Fill a rectangle with a given colour. This one is simple as it can
- * be done with the Amiga graphics primitives.
- */
-
- int
- amiga_fill_rectangle(gx_device *dev,int x,int y,int w,int h,gx_color_index color)
- {
- if(x < 0 || x > xdev -> width - w || y < 0 || y > xdev -> height - h)
- return(-1);
- else
- {
- if(w > 0 && h > 0 && color != gx_no_color_index)
- {
- amiga_set_pen(dev,color);
-
- RectFill(xdev -> rport,x,y,x + w - 1,y + h - 1);
- }
-
- return(0);
- }
- }
-
- /* amiga_copy_mono():
- *
- * Copy a monochrome image. This operation requires a bit of work as
- * we cannot simply blit the image into the bitmap.
- */
-
- int
- amiga_copy_mono(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)
- {
- if(y < 0 || x < 0 || w < 0 || h < 0)
- return(-1);
- else
- {
- if(w > 0 && h > 0)
- {
- LONG i,j;
-
- if(zero == gx_no_color_index)
- {
- if(one != gx_no_color_index)
- {
- do
- {
- ReadPixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- for(i = sourcex, j = 0 ; i < sourcex + w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- xdev -> temp_array[j] = one;
- }
-
- WritePixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
-
- y++;
- }
- while(--h);
- }
- }
- else
- {
- if(one == gx_no_color_index)
- {
- do
- {
- ReadPixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- for(i = sourcex, j = 0 ; i < w + sourcex ; i++, j++)
- {
- if(!(base[i >> 3] & shift[i & 7]))
- xdev -> temp_array[j] = zero;
- }
-
- WritePixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
-
- y++;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = 0 ; i < w + sourcex ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- xdev -> temp_array[j] = one;
- else
- xdev -> temp_array[j] = zero;
- }
-
- WritePixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
-
- y++;
- }
- while(--h);
- }
- }
- }
-
- return(0);
- }
- }
-
- /* amiga_copy_color():
- *
- * Copy a color image (oh well...). This is just the same as the
- * copy_mono() routine.
- */
-
- int
- amiga_copy_color(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)
- {
- if(y < 0 || x < 0 || w < 0 || h < 0)
- return(-1);
- else
- {
- if(w > 0 && h > 0)
- {
- LONG i,j;
-
- do
- {
- for(i = sourcex, j = 0 ; i < w + sourcex ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- xdev -> temp_array[j] = DarkPen;
- else
- xdev -> temp_array[j] = LightPen;
- }
-
- WritePixelLine8(xdev -> rport,x,y,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
-
- y++;
- }
- while(--h);
- }
-
- return(0);
- }
- }
-
- /* amiga_draw_line(gx_device *dev,int x0,int y0,int x1,int y1,gx_color_index color):
- *
- * Draw a line between two points. This one is easy as it can be done
- * with the Amiga graphics primitives, the only glitch is having to reset
- * the last dot to its original colour.
- */
-
- int
- amiga_draw_line(gx_device *dev,int x0,int y0,int x1,int y1,gx_color_index color)
- {
- if(color != gx_no_color_index && (x0 != x1 || y0 != y1))
- {
- LONG pen;
-
- pen = ReadPixel(xdev -> rport,x1,y1);
-
- amiga_set_pen(dev,color);
-
- Move(xdev -> rport,x0,y0);
- Draw(xdev -> rport,x1,y1);
-
- if(pen == color)
- {
- amiga_set_pen(dev,pen);
-
- WritePixel(xdev -> rport,x1,y1);
- }
- }
-
- return(0);
- }
-
- /* amiga_copy_mono_raw():
- *
- * Copy a monochrome image to a bitmap. Just watch the
- * astounding number of case switches.
- */
-
- int
- amiga_copy_mono_raw(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)
- {
- if(y < 0 || x < 0 || w < 0 || h < 0)
- return(-1);
- else
- {
- if(w > 0 && h > 0)
- {
- LONG i,j,modulo = xdev -> rport -> BitMap -> BytesPerRow;
- UBYTE *line;
-
- w += sourcex;
-
- line = xdev -> rport -> BitMap -> Planes[0] + y * xdev -> rport -> BitMap -> BytesPerRow;
-
- if(zero == gx_no_color_index)
- {
- if(one != gx_no_color_index)
- {
- if(one)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] |= shift[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] &= masks[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- }
- }
- else
- {
- if(one == gx_no_color_index)
- {
- if(zero)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(!(base[i >> 3] & shift[i & 7]))
- line[j >> 3] |= shift[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(!(base[i >> 3] & shift[i & 7]))
- line[j >> 3] &= masks[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- }
- else
- {
- if(one)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] |= shift[j & 7];
- else
- line[j >> 3] &= masks[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] &= masks[j & 7];
- else
- line[j >> 3] |= shift[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
- }
- }
- }
-
- return(0);
- }
- }
-
- /* amiga_copy_color_raw():
- *
- * Copy a color image (oh well...). This is just the same as the
- * copy_mono() routine.
- */
-
- int
- amiga_copy_color_raw(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)
- {
- if(y < 0 || x < 0 || w < 0 || h < 0)
- return(-1);
- else
- {
- if(w > 0 && h > 0)
- {
- LONG i,j,modulo = xdev -> rport -> BitMap -> BytesPerRow;
- UBYTE *line;
-
- line = xdev -> rport -> BitMap -> Planes[0] + y * xdev -> rport -> BitMap -> BytesPerRow;
-
- w += sourcex;
-
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- line[j >> 3] |= shift[j & 7];
- else
- line[j >> 3] &= masks[j & 7];
- }
-
- base += raster;
-
- line += modulo;
- }
- while(--h);
- }
-
- return(0);
- }
- }
-
- /* amiga_fill_rectangle_raw():
- *
- * Fill a rectangular area in a bitmap.
- */
-
- int
- amiga_fill_rectangle_raw(gx_device *dev,int x,int y,int w,int h,gx_color_index color)
- {
- if(x < 0 || x > xdev -> width - w || y < 0 || y > xdev -> height - h)
- return(-1);
- else
- {
- if(w > 0 && h > 0 && color != gx_no_color_index)
- {
- UBYTE *line,startmask,endmask;
- LONG right,mid,modulo = xdev -> rport -> BitMap -> BytesPerRow;
-
- right = x + w;
- mid = (right >> 3) - (x >> 3);
- line = xdev -> rport -> BitMap -> Planes[0] + y * xdev -> rport -> BitMap -> BytesPerRow + (x >> 3);
-
- x &= 7;
- right &= 7;
-
- if(color)
- {
- startmask = 0xFF >> x;
- endmask = ~(0xFF >> right);
-
- if(mid)
- {
- UBYTE *ptr;
- int i;
-
- do
- {
- ptr = line;
-
- *ptr++ |= startmask;
-
- i = mid;
-
- while(--i > 0)
- *ptr++ = 0xFF;
-
- *ptr |= endmask;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- startmask &= endmask;
-
- do
- {
- *line |= startmask;
-
- line += modulo;
- }
- while(--h);
- }
- }
- else
- {
- startmask = ~(0xFF >> x);
- endmask = 0xFF >> right;
-
- if(mid)
- {
- UBYTE *ptr;
- LONG i;
-
- do
- {
- ptr = line;
-
- *ptr++ &= startmask;
-
- i = mid;
-
- while(--i > 0)
- *ptr++ = 0x00;
-
- *ptr &= endmask;
-
- line += modulo;
- }
- while(--h);
- }
- else
- {
- startmask |= endmask;
-
- do
- {
- *line &= startmask;
-
- line += modulo;
- }
- while(--h);
- }
- }
- }
-
- return(0);
- }
- }
-
- /* amiga_draw_line_raw():
- *
- * Draw a hair line, your basic DDA algorithm;
- * keep your fingers crossed.
- */
-
- int
- amiga_draw_line_raw(gx_device *dev,int x,int y,int x1,int y1,gx_color_index color)
- {
- if(color != gx_no_color_index && (x != x1 || y != y1))
- {
- short xstep,ystep,dx,dy,diff,modulo;
- UBYTE *line,*plane,pen;
- LONG last;
-
- modulo = xdev -> rport -> BitMap -> BytesPerRow;
- plane = xdev -> rport -> BitMap -> Planes[0];
-
- line = &plane[y1 * modulo];
- last = y1;
- pen = line[x1 >> 3] & (x1 & 7);
-
- dx = x1 - x;
- dy = y1 - y;
-
- if(dx < 0)
- {
- dx = -dx;
- dy = -dy;
-
- x = x1;
- y = y1;
- }
-
- if(y != last)
- line = &plane[(last = y) * modulo];
-
- if(color)
- {
- line[x >> 3] |= shift[x & 7];
-
- xstep = ystep = 0;
-
- if(dy < 0)
- {
- if(dx > -dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep--;
-
- diff = diff - dy - dx;
- }
- else
- diff -= dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == -dy)
- diff = 0;
- else
- diff = -dy / 2;
-
- do
- {
- ystep--;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff - dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(ystep > dy);
- }
- }
- else
- {
- if(dx > dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep++;
-
- diff = diff + dy - dx;
- }
- else
- diff += dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == dy)
- diff = 0;
- else
- diff = dy / 2;
-
- do
- {
- ystep++;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff + dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(ystep < dy);
- }
- }
-
- if(!pen)
- {
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- else
- {
- line[x >> 3] &= masks[x & 7];
-
- xstep = ystep = 0;
-
- if(dy < 0)
- {
- if(dx > -dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep--;
-
- diff = diff - dy - dx;
- }
- else
- diff -= dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == -dy)
- diff = 0;
- else
- diff = -dy / 2;
-
- do
- {
- ystep--;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff - dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(ystep > dy);
- }
- }
- else
- {
- if(dx > dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep++;
-
- diff = diff + dy - dx;
- }
- else
- diff += dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == dy)
- diff = 0;
- else
- diff = dy / 2;
-
- do
- {
- ystep++;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff + dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(ystep < dy);
- }
- }
-
- if(pen)
- {
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= pen;
- }
- }
- }
-
- return(0);
- }
-
- /* amiga_open_ilbm(gx_device *dev):
- *
- * Open the ilbm device.
- */
-
- int
- amiga_open_ilbm(gx_device *dev)
- {
- if(xdev -> width <= 0 || xdev -> height <= 0)
- {
- if(xdev -> page_width > 0.0)
- xdev -> width = (int)(xdev -> x_pixels_per_inch * xdev -> page_width);
- else
- xdev -> width = 640;
-
- if(xdev -> page_height > 0.0)
- xdev -> height = (int)(xdev -> y_pixels_per_inch * xdev -> page_height);
- else
- xdev -> height = 512;
- }
-
- if(xdev -> rport = (struct RastPort *)AllocVec(sizeof(struct RastPort),MEMF_ANY))
- {
- InitRastPort(xdev -> rport);
-
- if(xdev -> bitmap = (struct BitMap *)AllocVec(sizeof(struct BitMap),MEMF_ANY))
- {
- InitBitMap(xdev -> bitmap,1,xdev -> width,xdev -> height);
-
- if(xdev -> bitplane = AllocVec(xdev -> bitmap -> Rows * xdev -> bitmap -> BytesPerRow,MEMF_ANY | MEMF_CLEAR))
- {
- xdev -> bitmap -> Planes[0] = xdev -> bitplane;
- xdev -> rport -> BitMap = xdev -> bitmap;
- xdev -> page_count = 1;
-
- DarkPen = 0;
- LightPen = 1;
-
- return(0);
- }
- else
- {
- char buffer[256];
-
- sprintf(buffer,"Ghostscript: failed to allocate raster (wanted %ld, largest %ld)",xdev -> bitmap -> Rows * xdev -> bitmap -> BytesPerRow,AvailMem(MEMF_ANY | MEMF_LARGEST));
-
- perror(buffer);
- }
- }
- else
- perror("Ghostscript: failed to allocate bitmap");
- }
- else
- perror("Ghostscript: failed to allocate raster port");
-
- return(-1);
- }
-
- /* amiga_output_page_ilbm(gx_device *dev,int,int):
- *
- * Send a bitmap to an IFF-ILBM file.
- */
-
- int
- amiga_output_page_ilbm(gx_device *dev,int num_copies,int flush)
- {
- const sigset_t trapped = sigmask(SIGINT);
- char buffer[270];
- LONG result = -1;
-
- sprintf(buffer,"%s_%04d.ilbm",xdev -> file_name,xdev -> page_count);
-
- fprintf(stdout,"\n\033[ASaving page Nº%d to \"%s\"...\033[K",xdev -> page_count,buffer);
- fflush(stdout);
-
- sigprocmask(SIG_BLOCK,&trapped,NULL);
-
- if(SaveBitMap(buffer,xdev -> bitmap,xdev -> width,xdev -> height,(UWORD)xdev -> x_pixels_per_inch,xdev -> y_pixels_per_inch))
- {
- fprintf(stdout,"\n\033[APage saved to file \"%s\".\033[K\n",buffer);
-
- result = 0;
-
- xdev -> page_count;
- }
- else
- perror("\n\033[AGhostscript: error saving page\033[K");
-
- sigprocmask(SIG_UNBLOCK,&trapped,NULL);
-
- return(result);
- }
-
- /* amiga_close_ilbm(gx_device *dev):
- *
- * Close the ilbm driver.
- */
-
- int
- amiga_close_ilbm(gx_device *dev)
- {
- if(xdev -> bitplane)
- {
- FreeVec(xdev -> bitplane);
-
- xdev -> bitplane = NULL;
- }
-
- if(xdev -> bitmap)
- {
- FreeVec(xdev -> bitmap);
-
- xdev -> bitmap = NULL;
- }
-
- if(xdev -> rport)
- {
- FreeVec(xdev -> rport);
-
- xdev -> rport = NULL;
- }
-
- xdev -> width = xdev -> height = 0;
- /* xdev -> x_pixels_per_inch = x_pixels_per_inch = 72.72;*/
-
- return(0);
- }
-
- private const gs_prop_item props_amiga[] =
- {
- prop_def("PageWidth", prt_string),
- prop_def("PageHeight", prt_string),
- prop_def("OutputFile", prt_string)
- };
-
- int
- amiga_get_props(gx_device *dev,gs_prop_item *plist)
- {
- int start = gx_default_get_props(dev,plist);
-
- if(plist != 0)
- {
- gs_prop_item *pi = plist + start;
-
- memcpy(pi,props_amiga,sizeof(props_amiga));
-
- pi[0] . value .a.p.s = "";
- pi[0] . value .a.size = -1;
-
- pi[1] . value .a.p.s = "";
- pi[1] . value .a.size = -1;
-
- pi[2] . value .a.p.s = "";
- pi[2] . value .a.size = -1;
- }
-
- return(start + (sizeof(props_amiga) / sizeof(gs_prop_item)));
- }
-
- int
- amiga_put_props(gx_device *dev,gs_prop_item *plist,int count)
- {
- gs_prop_item *known[3];
- LONG code = 0;
-
- props_extract(plist,count,props_amiga,3,known,0);
-
- if((code = gx_default_put_props(dev,plist,count)) < 0)
- return(code);
- else
- {
- if(known[0] != 0)
- {
- gs_prop_item *pn = known[0];
- LONG size = pn -> value . a . size;
- char temp[256];
-
- if(size >= 256)
- {
- pn -> status = pv_limitcheck;
-
- code = gs_error_limitcheck;
- }
- else
- {
- memcpy(temp,pn -> value . a . p . s,size);
-
- temp[size] = 0;
-
- xdev -> page_width = GetInches(temp);
-
- if(xdev -> page_width <= 0.0)
- {
- xdev -> page_width = 0.0;
-
- pn -> status = pv_limitcheck;
-
- code = gs_error_limitcheck;
- }
- else
- {
- if(code == 0)
- code = 1;
- }
- }
- }
-
- if(known[1] != 0)
- {
- gs_prop_item *pn = known[1];
- LONG size = pn -> value . a . size;
- char temp[256];
-
- if(size >= 256)
- {
- pn -> status = pv_limitcheck;
-
- code = gs_error_limitcheck;
- }
- else
- {
- memcpy(temp,pn -> value . a . p . s,size);
-
- temp[size] = 0;
-
- xdev -> page_height = GetInches(temp);
-
- if(xdev -> page_height <= 0.0)
- {
- xdev -> page_height = 0.0;
-
- pn -> status = pv_limitcheck;
-
- code = gs_error_limitcheck;
- }
- else
- {
- if(code == 0)
- code = 1;
- }
- }
- }
-
- if(known[2] != 0)
- {
- gs_prop_item *pn = known[2];
- LONG size = pn -> value . a . size;
-
- if(size >= 256)
- {
- pn -> status = pv_limitcheck;
-
- code = gs_error_limitcheck;
- }
- else
- {
- memcpy(xdev -> file_name,pn -> value . a . p . s,size);
-
- xdev -> file_name[size] = 0;
- }
- }
-
- if(code < 0)
- return_error(code);
-
- if(xdev -> is_open && code)
- {
- LONG ccode = gs_closedevice(dev);
-
- if(ccode < 0)
- return(ccode);
- }
-
- return(code);
- }
- }
-
- /* amiga_color_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue):
- *
- * Turn an RGB colour into a pen index.
- */
-
- gx_color_index
- amiga_color_map_rgb_color(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue)
- {
- LONG max = xdev -> cube_size - 1,r,g,b;
-
- r = (max * red) / gx_max_color_value;
- g = (max * green) / gx_max_color_value;
- b = (max * blue) / gx_max_color_value;
-
- return((r * xdev -> cube_size + g) * xdev -> cube_size + b);
- }
-
- /* amiga_color_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3]):
- *
- * Turn a pen index into RGB colour values.
- */
-
- int
- amiga_color_map_color_rgb(gx_device *dev,gx_color_index color,gx_color_value rgb[3])
- {
- LONG i,value,max = xdev -> cube_size - 1;
-
- for(i = 2 ; i >= 0 ; i--)
- {
- value = color % xdev -> cube_size;
-
- rgb[i] = (gx_max_color_value * value) / max;
-
- color /= xdev -> cube_size;
- }
-
- return(0);
- }
-
- /* amiga_color_map_rgb_color_pen(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue):
- *
- * Turn an RGB colour into a pen index; this routine takes remapped
- * pens into account.
- */
-
- gx_color_index
- amiga_color_map_rgb_color_pen(gx_device *dev,gx_color_value red,gx_color_value green,gx_color_value blue)
- {
- LONG max = xdev -> cube_size - 1,r,g,b;
-
- r = (max * red) / gx_max_color_value;
- g = (max * green) / gx_max_color_value;
- b = (max * blue) / gx_max_color_value;
-
- return(xdev -> pens[(r * xdev -> cube_size + g) * xdev -> cube_size + b]);
- }
-
- /* amiga_color_map_color_rgb_pen(gx_device *dev,gx_color_index color,gx_color_value rgb[3]):
- *
- * Turn a pen index into RGB colour values; this routine takes remapped
- * pens into account.
- */
-
- int
- amiga_color_map_color_rgb_pen(gx_device *dev,gx_color_index color,gx_color_value rgb[3])
- {
- LONG i,value,max = xdev -> cube_size - 1;
-
- /* Find the matching pen... */
-
- for(i = 0 ; i < xdev -> cube_size * xdev -> cube_size * xdev -> cube_size ; i++)
- {
- if(xdev -> pens[i] == color)
- {
- color = i;
-
- break;
- }
- }
-
- for(i = 2 ; i >= 0 ; i--)
- {
- value = color % xdev -> cube_size;
-
- rgb[i] = (gx_max_color_value * value) / max;
-
- color /= xdev -> cube_size;
- }
-
- return(0);
- }
-
- /* amiga_copy_color8():
- *
- * Copy a color image, the source is guaranteed to consist of
- * one byte per colour.
- */
-
- int
- amiga_copy_color8(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)
- {
- if(y < 0 || x < 0 || w < 0 || h < 0)
- return(-1);
- else
- {
- if(w > 0 && h > 0)
- {
- base += sourcex;
-
- if(w > xdev -> width)
- w = xdev -> width;
-
- do
- {
-
- CopyMem((UBYTE *)base,xdev -> temp_array,w);
-
- WritePixelLine8(xdev -> rport,x,y++,w,xdev -> temp_array,xdev -> temp_rport);
-
- base += raster;
- }
- while(--h);
- }
-
- return(0);
- }
- }
-
- /* amiga_copy_mono_raw_color():
- *
- * Copy a monochrome image to a bitmap.
- */
-
- int
- amiga_copy_mono_raw_color(gx_device *dev,const UBYTE *base,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)
- {
- if(y < 0 || x < 0 || w < 0 || h < 0)
- return(-1);
- else
- {
- if(w > 0 && h > 0 && zero != gx_no_color_index && one != gx_no_color_index)
- {
- PLANEPTR line[12];
- LONG i,j,k,modulo = xdev -> rport -> BitMap -> BytesPerRow,depth = xdev -> rport -> BitMap -> Depth;
-
- for(i = 0 ; i < depth ; i++)
- line[i] = xdev -> rport -> BitMap -> Planes[i] + y * modulo;
-
- w += sourcex;
-
- if(zero == gx_no_color_index)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(one & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
- }
-
- base += raster;
-
- for(k = 0 ; k < depth ; k++)
- line[k] += modulo;
- }
- while(--h);
- }
- else
- {
- if(one == gx_no_color_index)
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(zero & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
- }
-
- base += raster;
-
- for(k = 0 ; k < depth ; k++)
- line[k] += modulo;
- }
- while(--h);
- }
- else
- {
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- if(base[i >> 3] & shift[i & 7])
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(one & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
- else
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(zero & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
- }
-
- base += raster;
-
- for(k = 0 ; k < depth ; k++)
- line[k] += modulo;
- }
- while(--h);
- }
- }
- }
-
- return(0);
- }
- }
-
- /* amiga_copy_color_raw_color16():
- *
- * Copy a color image, the source data is guaranteed to consist
- * of one word per colour.
- */
-
- int
- amiga_copy_color_raw_color16(gx_device *dev,const UBYTE *data,int sourcex,int raster,gx_bitmap_id id,int x,int y,int w,int h)
- {
- if(y < 0 || x < 0 || w < 0 || h < 0)
- return(-1);
- else
- {
- if(w > 0 && h > 0)
- {
- PLANEPTR line[12];
- LONG i,j,k,modulo = xdev -> rport -> BitMap -> BytesPerRow,depth = xdev -> rport -> BitMap -> Depth;
- UWORD *base = (UWORD *)data;
-
- for(i = 0 ; i < depth ; i++)
- line[i] = xdev -> rport -> BitMap -> Planes[i] + y * modulo;
-
- w += sourcex;
-
- raster /= 2;
-
- do
- {
- for(i = sourcex, j = x ; i < w ; i++, j++)
- {
- for(k = 0 ; k < depth ; k++)
- {
- if(base[i] & (1 << k))
- line[k][j >> 3] |= shift[j & 7];
- else
- line[k][j >> 3] &= masks[j & 7];
- }
- }
-
- base += raster;
-
- for(k = 0 ; k < depth ; k++)
- line[k] += modulo;
- }
- while(--h);
- }
-
- return(0);
- }
- }
-
- /* amiga_fill_rectangle_raw_color():
- *
- * Fill a rectangular area in a bitmap.
- */
-
- int
- amiga_fill_rectangle_raw_color(gx_device *dev,int x,int y,int w,int h,gx_color_index color)
- {
- if(x < 0 || x > xdev -> width - w || y < 0 || y > xdev -> height - h)
- return(-1);
- else
- {
- if(w > 0 && h > 0 && color != gx_no_color_index)
- {
- PLANEPTR line[12];
- LONG i,j,right,mid,modulo = xdev -> rport -> BitMap -> BytesPerRow,depth = xdev -> rport -> BitMap -> Depth;
-
- for(i = 0 ; i < depth ; i++)
- line[i] = xdev -> rport -> BitMap -> Planes[i] + y * modulo + (x >> 3);
-
- right = x + w;
- mid = (right >> 3) - (x >> 3);
-
- x &= 7;
- right &= 7;
-
- if(mid)
- {
- UBYTE *ptr;
-
- do
- {
- for(j = 0 ; j < depth ; j++)
- {
- ptr = line[j];
-
- i = mid;
-
- if(color & (1 << j))
- {
- *ptr++ |= 0xFF >> x;
-
- while(--i > 0)
- *ptr++ = 0xFF;
-
- *ptr |= ~(0xFF >> right);
- }
- else
- {
- *ptr++ &= ~(0xFF >> x);
-
- while(--i > 0)
- *ptr++ = 0x00;
-
- *ptr &= 0xFF >> right;
- }
-
- line[j] += modulo;
- }
- }
- while(--h);
- }
- else
- {
- UBYTE one_mask = (0xFF >> x) & ~(0xFF >> right),
- zero_mask = ~(0xFF >> x) | (0xFF >> right);
- do
- {
- for(j = 0 ; j < depth ; j++)
- {
- if(color & (1 << j))
- *line[j] |= one_mask;
- else
- *line[j] &= zero_mask;
-
- line[j] += modulo;
- }
- }
- while(--h);
- }
- }
-
- return(0);
- }
- }
-
- /* amiga_draw_line_raw_color():
- *
- * Draw a hair line, your basic DDA algorithm;
- * keep your fingers crossed.
- */
-
- int
- amiga_draw_line_raw_color(gx_device *dev,int x,int y,int x1,int y1,gx_color_index color)
- {
- if(color != gx_no_color_index && (x != x1 || y != y1))
- {
- LONG xstep,ystep,dx,dy,diff,modulo;
- UBYTE *line,*plane,pen;
- LONG last,i,orig_x = x,orig_y = y;
-
- modulo = xdev -> rport -> BitMap -> BytesPerRow;
-
- for(i = 0 ; i < xdev -> rport -> BitMap -> Depth ; i++)
- {
- plane = xdev -> rport -> BitMap -> Planes[i];
- line = &plane[y1 * modulo];
- last = y1;
- pen = line[x1 >> 3] & (x1 & 7);
- x = orig_x;
- y = orig_y;
-
- dx = x1 - x;
- dy = y1 - y;
-
- if(dx < 0)
- {
- dx = -dx;
- dy = -dy;
-
- x = x1;
- y = y1;
- }
-
- if(y != last)
- line = &plane[(last = y) * modulo];
-
- if(color & (1 << i))
- {
- line[x >> 3] |= shift[x & 7];
-
- xstep = ystep = 0;
-
- if(dy < 0)
- {
- if(dx > -dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep--;
-
- diff = diff - dy - dx;
- }
- else
- diff -= dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == -dy)
- diff = 0;
- else
- diff = -dy / 2;
-
- do
- {
- ystep--;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff - dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(ystep > dy);
- }
- }
- else
- {
- if(dx > dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep++;
-
- diff = diff + dy - dx;
- }
- else
- diff += dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == dy)
- diff = 0;
- else
- diff = dy / 2;
-
- do
- {
- ystep++;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff + dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= shift[x1 & 7];
- }
- }
- while(ystep < dy);
- }
- }
-
- if(!pen)
- {
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- else
- {
- line[x >> 3] &= masks[x & 7];
-
- xstep = ystep = 0;
-
- if(dy < 0)
- {
- if(dx > -dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep--;
-
- diff = diff - dy - dx;
- }
- else
- diff -= dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == -dy)
- diff = 0;
- else
- diff = -dy / 2;
-
- do
- {
- ystep--;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff - dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(ystep > dy);
- }
- }
- else
- {
- if(dx > dy)
- {
- diff = -dx / 2;
-
- do
- {
- xstep++;
-
- if(diff > 0)
- {
- ystep++;
-
- diff = diff + dy - dx;
- }
- else
- diff += dy;
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(xstep < dx);
- }
- else
- {
- if(dx == dy)
- diff = 0;
- else
- diff = dy / 2;
-
- do
- {
- ystep++;
-
- if(diff > 0)
- diff -= dx;
- else
- {
- xstep++;
-
- diff = diff + dy - dx;
- }
-
- {
- LONG x1 = x + xstep,y1 = y + ystep;
-
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] &= masks[x1 & 7];
- }
- }
- while(ystep < dy);
- }
- }
-
- if(pen)
- {
- if(y1 != last)
- line = &plane[(last = y1) * modulo];
-
- line[x1 >> 3] |= pen;
- }
- }
- }
- }
-
- return(0);
- }
-