|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 12366 (0x304e) Types: TextFile Names: »spixline.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─⟦this⟧ »./X.V10R4/libibm/libsrc/spixline.c«
#ifndef lint static char *rcsid_spixline_c = "$Header: spixline.c,v 10.1 86/11/19 10:44:12 jg Exp $"; #endif lint /* spixline.c - single pixel wide line drawing routine * * SinglePixelLine draws solid, dashed and patterned lines * that are only one pixel wide * * Author: * Scott Bates * Brown University * IRIS, Box 1946 * Providence, RI 02912 * * * Copyright (c) 1986 Brown University * * Permission to use, copy, modify and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies, and that both * that copyright notice and this permission notice appear in supporting * documentation, and that the name of Brown University not be used in * advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Brown University makes no * representations about the suitability of this software for any purpose. * It is provided "as-is" without express or implied warranty. */ #include "private.h" #include "bitblt.h" #include "spixline.h" /* * Draw single pixel wide line */ SinglePixelLine (BitMap, StartX, StartY, StopX, StopY, Clip, Rule, Mode, SrcPix, AltPix, Pattern, PatternLength, PatternMultiplier) BITMAP *BitMap; int StartX, StartY; int StopX, StopY; CLIP *Clip; int Rule, Mode; int SrcPix, AltPix; u_short Pattern; int PatternLength; int PatternMultiplier; { register u_short MaskBit, *Destination, Source; register BitsLeftToDraw, Sentinel, NumberOfBytes; int DeltaX, DeltaY, Temp, RepeatCount; u_short AltSource, PatternFirstBit, PatternBit; int NumberOfShorts; #if (defined(AED) || defined(APA8) || defined(APA8C)) struct Blt_Rectangle Rect; #endif (AED || APA8 || APA8C) #if (defined(APA8) || defined(APA8C)) long DestinationIncrement; #endif (APA8 || APA8C) #ifdef AED int EchoLine = 1; /* * If the destination is the screen and were not drawing a patterned * line use the AED microcode to draw it. If the microcode is used * then the blt does not have to be echoed to the AED to make visible. * * NOTE: If we are drawing a dashed line and the multiplier * is equal to one then use the AED microcode. Otherwise, * do it in software and then echo it to the AED. */ if(BitMap == SCREEN_BITMAP && Mode != DrawPatternedLine) { if (Mode == DrawSolidLine) { ClipToRect(Clip, &Rect); aed_draw_line(StartX, StartY, StopX, StopY, Rule, 1, (SrcPix & 1), (u_short)0, 0, &Rect); EchoLine = 0; } else if (PatternMultiplier < 2) { ClipToRect(Clip, &Rect); aed_draw_line(StartX, StartY, StopX, StopY, Rule, 1, (SrcPix & 1), Pattern, PatternLength, &Rect); EchoLine = 0; } } #endif AED #ifdef TRACE_X fprintf(stderr, "In SinglePixelLine\n"); fflush(stderr); #endif TRACE_X /* * Clip line. If nothing to draw after clip * return to caller. */ ClipLine(StartX, StartY, StopX, StopY, Clip); /* * Always draw left to right */ if (StopX < StartX) { Temp = StopX, StopX = StartX, StartX = Temp; Temp = StopY, StopY = StartY, StartY = Temp; } /* * Compute delta values and bitmap width in shorts */ DeltaX = StopX - StartX; DeltaY = StopY - StartY; NumberOfShorts = (BitMap->width + 15) / 16; #if (defined(APA8) || defined(APA8C)) if (DeltaY > 0) { /* drawing top to bottom */ if (BitMap == SCREEN_BITMAP) NumberOfBytes = NumberOfShorts << 2; else NumberOfBytes = NumberOfShorts << 1; } else { /* drawing bottom to top */ if (BitMap == SCREEN_BITMAP) NumberOfBytes = -(NumberOfShorts << 2); else NumberOfBytes = -(NumberOfShorts << 1); DeltaY = -DeltaY; } #else if (DeltaY > 0) { /* drawing top to bottom */ NumberOfBytes = NumberOfShorts << 1; } else { /* drawing bottom to top */ NumberOfBytes = -(NumberOfShorts << 1); DeltaY = -DeltaY; } #endif (APA8 || APA8C) /* * Get source and alternate tiles */ Source = *ConstantTiles[SrcPix & 1]; if(Mode == DrawPatternedLine) AltSource = *ConstantTiles[AltPix & 1]; /* * Compute starting destination address */ #if (defined(APA8) || defined (APA8C)) if (BitMap == SCREEN_BITMAP) { Destination = (u_short *) BitMap->data + ((StartX / 16 + StartY * NumberOfShorts) << 1); DestinationIncrement = 4; } else { Destination = (u_short *) BitMap->data + StartX / 16 + StartY * NumberOfShorts; DestinationIncrement = 2; } #else Destination = (u_short *) BitMap->data + StartX / 16 + StartY * NumberOfShorts; #endif (APA8 || APA8C) /* * set mask to select starting bit */ MaskBit = 0x8000 >> (StartX & 0x0F); /* * If this is not a solid line setup pattern values */ if (Mode != DrawSolidLine) { RepeatCount = PatternMultiplier; PatternFirstBit = 1 << (PatternLength - 1); PatternBit = PatternFirstBit; } #ifdef SOFTWARE_CURSOR /* * Save cursor if blt is to screen */ if (BitMap == SCREEN_BITMAP) { if (save_cursor(MIN(StopX, StartX), MIN(StopY, StartY), MAX(StopX, StartX) + 1, MAX(StopY, StartY) + 1) < 0) { DeviceError( "SinglePixelLine: ioctl QIOCHIDECUR failed.\n" ); } } #endif SOFTWARE_CURSOR /* * draw the line */ if (DeltaX > DeltaY) { /* This is a horizontal line */ Sentinel = DeltaX >> 1; BitsLeftToDraw = DeltaX; switch (Rule) { case (GXor): HORIZONTAL_LINE ( {*Destination |= (Source & MaskBit);}, {*Destination |= (AltSource & MaskBit);} ); break; case (GXcopy): HORIZONTAL_LINE ( {*Destination = (*Destination & ~MaskBit) | (Source & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | (AltSource & MaskBit);} ); break; case (GXxor): HORIZONTAL_LINE ( {*Destination ^= (Source & MaskBit);}, {*Destination ^= (AltSource & MaskBit);} ); break; case (GXset): HORIZONTAL_LINE ( {*Destination |= MaskBit;}, {*Destination |= MaskBit;} ); break; case (GXclear): HORIZONTAL_LINE ( {*Destination &= ~MaskBit;}, {*Destination &= ~MaskBit;} ); break; case (GXinvert): HORIZONTAL_LINE ( {*Destination ^= MaskBit;}, {*Destination ^= MaskBit;} ); break; case (GXcopyInverted): HORIZONTAL_LINE ( {*Destination = (*Destination & ~MaskBit) | (~Source & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | (~AltSource & MaskBit);} ); break; case (GXandInverted): HORIZONTAL_LINE ( {*Destination &= ~(Source & MaskBit);}, {*Destination &= ~(AltSource & MaskBit);} ); break; case (GXorReverse): HORIZONTAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((~*Destination | Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((~*Destination | AltSource) & MaskBit);} ); break; case (GXequiv): HORIZONTAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((*Destination ^ ~Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((*Destination ^ ~AltSource) & MaskBit);} ); break; case (GXnand): HORIZONTAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((~*Destination | ~Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((~*Destination | ~AltSource) & MaskBit);} ); break; case (GXnor): HORIZONTAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((~*Destination & ~Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((~*Destination & ~AltSource) & MaskBit);} ); break; case (GXandReverse): HORIZONTAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((~*Destination & Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((~*Destination & AltSource) & MaskBit);} ); break; case (GXand): HORIZONTAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((*Destination & Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((*Destination & AltSource) & MaskBit);} ); break; case (GXorInverted): HORIZONTAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((*Destination | ~Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((*Destination | ~AltSource) & MaskBit);} ); } } else { /* This is a vertical line */ Sentinel = DeltaY >> 1; BitsLeftToDraw = DeltaY; switch (Rule) { case (GXor): VERTICAL_LINE ( {*Destination |= (Source & MaskBit);}, {*Destination |= (AltSource & MaskBit);} ); break; case (GXcopy): VERTICAL_LINE ( {*Destination = (*Destination & ~MaskBit) | (Source & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | (AltSource & MaskBit);} ); break; case (GXxor): VERTICAL_LINE ( {*Destination ^= (Source & MaskBit);}, {*Destination ^= (AltSource & MaskBit);} ); break; case (GXset): VERTICAL_LINE ( {*Destination |= MaskBit;}, {*Destination |= MaskBit;} ); break; case (GXclear): VERTICAL_LINE( {*Destination &= ~MaskBit;}, {*Destination &= ~MaskBit;} ); break; case (GXinvert): VERTICAL_LINE ( {*Destination ^= MaskBit;}, {*Destination ^= MaskBit;} ); break; case (GXcopyInverted): VERTICAL_LINE ( {*Destination = (*Destination & ~MaskBit) | (~Source & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | (~AltSource & MaskBit);} ); break; case (GXandInverted): VERTICAL_LINE ( {*Destination &= ~(Source & MaskBit);}, {*Destination &= ~(AltSource & MaskBit);} ); break; case (GXorReverse): VERTICAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((~*Destination | Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((~*Destination | AltSource) & MaskBit);} ); break; case (GXequiv): VERTICAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((*Destination ^ ~Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((*Destination ^ ~AltSource) & MaskBit);} ); break; case (GXnand): VERTICAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((~*Destination | ~Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((~*Destination | ~AltSource) & MaskBit);} ); break; case (GXnor): VERTICAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((~*Destination & ~Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((~*Destination & ~AltSource) & MaskBit);} ); break; case (GXandReverse): VERTICAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((~*Destination & Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((~*Destination & AltSource) & MaskBit);} ); break; case (GXand): VERTICAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((*Destination & Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((*Destination & AltSource) & MaskBit);} ); break; case (GXorInverted): VERTICAL_LINE ( {*Destination = (*Destination & ~MaskBit) | ((*Destination | ~Source) & MaskBit);}, {*Destination = (*Destination & ~MaskBit) | ((*Destination | ~AltSource) & MaskBit);} ); } } #ifdef SOFTWARE_CURSOR /* * Restore cursor to screen */ if (BitMap == SCREEN_BITMAP) { if (restore_cursor() < 0) { DeviceError("SinglePixelLine: ioctl QIOCSHOWCUR failed.\n"); } } #endif SOFTWARE_CURSOR #ifdef AED /* * Unable to use microcode to draw the line. * Therefore, it must be echoed to the * AED screen to become visible. */ if (EchoLine) { changed_rect.origin_y = MIN(StopY, StartY); changed_rect.origin_x = MIN(StopX, StartX); changed_rect.corner_y = MAX(StopY, StartY) + 1; changed_rect.corner_x = MAX(StopX, StartX) + 1; aed_echo_rect(&changed_rect); } #endif AED }