/* * AMIGA.C: This is the Graphics Window interface to MetaFont for online * displays on the Commodore Amiga. This file was written by Edmund Mergl * for his Amiga port of TeX 3.1 and MetaFont 2.7 from the original Unix * sources (see Fish Disks 611-616). * * Some modifications and improvements were made since 1993 by Andreas and * Stefan Scherer, Abt-Wolf-Strasse 17, 96215 Lichtenfels, Germany. The * most recent entries from top to bottom always superseed their ancestors, * just read this as a bit of history: * * August 12, 1993: * * - We use the `memory hack', so the values for `screenwidth' * and `screendepth' are to be found in `mfmemory.config'. The * display height should be set to an InterLace value, this will * be dealt with by `lacefactor' (see below). * * - The display window is no longer resizeable, because no * `screenupdate' is called and the picture is destroyed. * * - Based on ideas by Stefan Becker used in his famous MetaFont port * to the Amiga of 1991 (see Fish Disk 486) there is a variable * `scalefactor', which can be set to a (small) positiv integer in * `mfmemory.config'. This results in a reduced size of the displayed * characters, so that large font pictures can be drawn on * small-sized screens (although some distortions are possible). * * - By replacing `Move' and `Draw' with `WritePixelLine' and friends * the speed of the display was heavily increased. * * - The display screen is totally controlled by `screenwidth' and * `screendepth' from `mfmemory.config', when you set `screen_rows' * and `screen_cols' both to the maximum value `4095' in your local * device modes file. MetaFont takes the smaller of these pairs. * * - `blankrectangle' *always* set the complete display window to the * background color, not only the area specified by `left', `right', * `top', and `bottom'. These MetaFont coordinates are now obeyed. * * September 11, 1993: * * - The changes for `Computers and Typesetting -- Volume A-E' provided * by Addison-Wesley Publishing Company resulted in MetaFont 2.71. * This caused a change in the window title. * * October 22, 1993: * * - The official version 2.71 has the same window title. :-) * * January 28, 1994: * * - Although SAS/C has an AutoOpen feature for Amiga libraries, * it is better to define the library bases explicitly. * * February 15, 1995: * * - Here's my new address: * Andreas Scherer, Rolandstraße 16, 52070 Aachen, Germany. * (Internet). * - Make `amiga.c' compliant with the syntax of the other modules * in the Web2C 6.1 distribution. * * February 19, 1995: * * - `close_all()' must not have arguments, because we want to * link it into the `atexit()' function list. * - To distinguish this version from the old distribution, the * window title is modified. * * March 23, 1995: * * - MetaFont has the new version number 2.718. * * April 9, 1995: * * - rename `screenheight' to `screendepth' for consistency. * * October 10, 1995: * * - Yet another change in my address, now it's a UNIX CIP pool: * * - Cleanup for the new web2c release. * * January 20, 2010: * * - MetaFont has the new version number 2.718281. */ #define EXTERN extern #include "../mfd.h" #ifdef AMIGAWIN /* Whole file */ #include #include #include struct GfxBase *GfxBase; struct IntuitionBase *IntuitionBase; struct Screen *Scr; struct Window *Win; struct BitMap tempbm; struct RastPort temprp; UBYTE *linearray; int scaledwidth = 0; int scaledheight = 0; #ifndef scalefactor #define scalefactor 1 #endif /* * The configuration `mf.mcf' of AmiWeb2C holds values for `screenwidth' * and `screendepth' that always refer to an InterLace screen. In case * you open the display on a non-InterLaced screen, only half the lines * are shown to you. This is automatically done by reading the screen * information and setting `lacefactor'. */ int lacefactor; #define BACKGROUNDCOLOR 0 #define PENCOLOR 1 #define PUBSCREEN 0 /* * Allocating memory for the array used in `WritePixelLine' needs * WORD-aligned arguments. */ #define ALIGN_SIXTEEN_BIT(A) ((((A)+15)/16)*16) #ifndef min #define min(a,b) ((a)<(b)?(a):(b)) #endif /* * CLOSE_ALL: Clean up on MetaFont termination. This routine has to be * called just before leaving the program, which is done automatically * when it gets entered into the `atexit' function list. (See below.) */ void close_all(void) { if (linearray) free(linearray); if (tempbm.Planes[0]) FreeRaster(tempbm.Planes[0], scaledwidth, 1); if (Win) CloseWindow(Win); if (GfxBase) CloseLibrary((struct Library *)GfxBase); if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase); } /* close_all() */ #include /* * INITSCREEN: Initialize the physical display window on the WorkBench * screen of the Commodore Amiga. Open the necessary libraries and open * the window according to `screenwidth' and `screendepth' as given in * the configuration file `mf.mcf'. For this purpose, the * `OpenWindowTagList' routine was replaced with `OpenWindowTags'. * The `WFLG_SIZEGADGET' window flag has been removed; resizing the * window kills the picture and never triggered an `updatescreen'. */ int mf_amiga_initscreen(void) { #ifdef DEBUG printf("\ninitscreen()\n"); #endif /* * Make sure the resources are correctly returned to the system * when leaving the program. */ if(atexit(&close_all)) { /* Can't happen. */ fprintf(stderr, "Exit trap failure! (close_all)\n"); uexit(1); } if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary((unsigned char *)"intuition.library",(unsigned long)37L))) { fprintf(stderr,"\nCan't open intuition library. V37 required.\n"); close_all(); return(FALSE); } if (!(GfxBase = (struct GfxBase *) OpenLibrary((unsigned char *)"graphics.library",(unsigned long)37L))) { fprintf(stderr,"\nCan't open intuition library. V37 required.\n"); close_all(); return(FALSE); } if (!(Scr = LockPubScreen(PUBSCREEN))) { fprintf(stderr, "\nCan't get lock on public screen (%d).\n", PUBSCREEN); close_all(); return(FALSE); } scaledwidth = screenwidth/scalefactor; scaledheight = screendepth/scalefactor; lacefactor = ((Scr->ViewPort.Modes & LACE) ? 1 : 2); if (!(Win = (struct Window *)OpenWindowTags( NULL, WA_InnerWidth, scaledwidth, WA_InnerHeight, scaledheight/lacefactor, WA_Flags, WFLG_DRAGBAR|WFLG_DEPTHGADGET, WA_AutoAdjust, FALSE, WA_Title, (ULONG)" MetaFont V2.718281 Online Display", WA_PubScreen, (ULONG)Scr, TAG_DONE))) { fprintf(stderr, "\nCan't open online display window at size %d times %d.\n" #ifdef VARMEM "Change your configuration file.\n", #else "If you really absolutely need more capacity,\n" "you can ask a wizard to enlarge me.\n", #endif screenwidth,screendepth); close_all(); return(FALSE); } InitBitMap(&tempbm, 1, scaledwidth, 1); tempbm.Planes[0] = NULL; if(!(tempbm.Planes[0] = (PLANEPTR)AllocRaster(scaledwidth, 1))) return(FALSE); InitRastPort(&temprp); temprp.BitMap = &tempbm; if(!(linearray = (UBYTE *) calloc(ALIGN_SIXTEEN_BIT(scaledwidth),sizeof(UBYTE)))) return(FALSE); UnlockPubScreen(NULL, Scr); #ifdef DEBUG printf("initscreen() ok\n"); #endif return(TRUE); } /* mf_amiga_initscreen() */ /* * UPDATESCREEN: I really don't know what this function is supposed * to do. */ void mf_amiga_updatescreen(void) { #ifdef DEBUG printf("updatescreen()\n"); #endif } /* mf_amiga_update_screen() */ /* * BLANKRECTANGLE: Reset the drawing rectangle bounded by * ([left,right],[top,bottom]) to the background color. */ void mf_amiga_blankrectangle(screencol left, screencol right, screenrow top, screenrow bottom) { #ifdef DEBUG printf("blankrectangle() - left: %d right: %d top: %d bottom: %d\n", left, right, top, bottom); #endif SetAPen (Win->RPort, BACKGROUNDCOLOR); RectFill(Win->RPort, (SHORT)(Win->BorderLeft + left/scalefactor), (SHORT)(Win->BorderTop + top/(scalefactor*lacefactor)), (SHORT)(Win->BorderLeft + right/scalefactor - 1), (SHORT)(Win->BorderTop + bottom/(scalefactor*lacefactor) - 1)); } /* mf_amiga_blankrectangle() */ /* * PAINTROW: Paint a `row' starting with color `init_color', up to the * next transition specified by `transition_vector', switch colors, and * continue for `vector_size' transitions. It now only * draws into the display window when a new raster line will be affected. * A lot of pre-drawing and inter-drawing calculations and conditionals * are evaluated to prepare a fast and clean drawing under the most * circumstances to be expected on the Amiga. InterLace/Lace is taken * care of and the sizes are set appropriately not to clobber the borders. * (Don't ask me why this works; at least on my machine with my config.) */ void mf_amiga_paintrow(screenrow row, pixelcolor init_color, transspec transition_vector, screencol vector_size) { int start, scaledstart, scaledrow, scaledlaced; register int i=0, j=0, col, color; #ifdef DEBUG printf("paintrow() - vector size: %d\n", vector_size); #endif color = ((0 == init_color) ? BACKGROUNDCOLOR : PENCOLOR); scaledlaced = scalefactor * lacefactor; start = *transition_vector++; scaledstart = start / scalefactor; scaledrow = row / scaledlaced; ReadPixelLine8(Win->RPort, Win->BorderLeft + scaledstart, Win->BorderTop + scaledrow, scaledwidth - scaledstart, linearray, &temprp); if(scalefactor>1) { do { for(col = *transition_vector++; i= col-start) linearray[++j] |= color; } else { do { for(col = *transition_vector++; jBorderTop + scaledrow ) < ( Win->Height - Win->BorderBottom ) ) WritePixelLine8(Win->RPort, Win->BorderLeft + scaledstart, Win->BorderTop + scaledrow, min(Win->Width - Win->BorderLeft - Win->BorderRight - scaledstart,j), linearray, &temprp); } /* mf_amiga_paintrow() */ #else int amiga_dummy; #endif /* AMIGAWIN */