Annotation of 43BSDTahoe/new/X/libibm/libsrc/spixline.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *rcsid_spixline_c = "$Header: spixline.c,v 10.1 86/11/19 10:44:12 jg Exp $";
                      3: #endif lint
                      4: /* spixline.c - single pixel wide line drawing routine
                      5:  *
                      6:  *     SinglePixelLine draws solid, dashed and patterned lines
                      7:  *                     that are only one pixel wide
                      8:  *
                      9:  *     Author:
                     10:  *             Scott Bates
                     11:  *             Brown University
                     12:  *             IRIS, Box 1946
                     13:  *             Providence, RI 02912
                     14:  *
                     15:  *
                     16:  *             Copyright (c) 1986 Brown University
                     17:  *
                     18:  * Permission to use, copy, modify and distribute this software and its
                     19:  * documentation for any purpose and without fee is hereby granted, provided
                     20:  * that the above copyright notice appear in all copies, and that both
                     21:  * that copyright notice and this permission notice appear in supporting
                     22:  * documentation, and that the name of Brown University not be used in
                     23:  * advertising or publicity pertaining to distribution of the software
                     24:  * without specific, written prior permission. Brown University makes no
                     25:  * representations about the suitability of this software for any purpose.
                     26:  * It is provided "as-is" without express or implied warranty.
                     27:  */
                     28: 
                     29: #include "private.h"
                     30: #include "bitblt.h"
                     31: #include "spixline.h"
                     32: 
                     33: /*
                     34:  * Draw single pixel wide line
                     35:  */
                     36: 
                     37: SinglePixelLine (BitMap, StartX, StartY, StopX, StopY, Clip, Rule, Mode,
                     38:                 SrcPix, AltPix, Pattern, PatternLength, PatternMultiplier)
                     39:        BITMAP *BitMap;
                     40:        int StartX, StartY;
                     41:        int StopX, StopY;
                     42:        CLIP *Clip;
                     43:        int Rule, Mode;
                     44:        int SrcPix, AltPix;
                     45:        u_short Pattern;
                     46:        int PatternLength;
                     47:        int PatternMultiplier;
                     48: {
                     49:        register u_short MaskBit, *Destination, Source;
                     50:        register BitsLeftToDraw, Sentinel, NumberOfBytes;
                     51:        int DeltaX, DeltaY, Temp, RepeatCount;
                     52:        u_short AltSource, PatternFirstBit, PatternBit;
                     53:        int NumberOfShorts;
                     54: #if (defined(AED) || defined(APA8) || defined(APA8C))
                     55:        struct Blt_Rectangle Rect;
                     56: #endif (AED || APA8 || APA8C)
                     57: #if (defined(APA8) || defined(APA8C))
                     58:        long DestinationIncrement;
                     59: #endif (APA8 || APA8C)
                     60: #ifdef AED
                     61:        int EchoLine = 1;
                     62: 
                     63:        /*
                     64:         * If the destination is the screen and were not drawing a patterned
                     65:         * line use the AED microcode to draw it. If the microcode is used 
                     66:         * then the blt does not have to be echoed to the AED to make visible.
                     67:         *
                     68:         * NOTE: If we are drawing a dashed line and the multiplier
                     69:         *       is equal to one then use the AED microcode. Otherwise,
                     70:         *       do it in software and then echo it to the AED.
                     71:         */
                     72: 
                     73:        if(BitMap == SCREEN_BITMAP && Mode != DrawPatternedLine) {
                     74: 
                     75:                if (Mode == DrawSolidLine) {
                     76:                        ClipToRect(Clip, &Rect);
                     77:                        aed_draw_line(StartX, StartY, StopX, StopY, Rule, 1,
                     78:                                (SrcPix & 1), (u_short)0, 0, &Rect);
                     79:                        EchoLine = 0;
                     80:                } else  if (PatternMultiplier < 2) {
                     81:                        ClipToRect(Clip, &Rect);
                     82:                        aed_draw_line(StartX, StartY, StopX, StopY, Rule, 1,
                     83:                                (SrcPix & 1), Pattern, PatternLength, &Rect);
                     84:                        EchoLine = 0;
                     85:                }
                     86:        }
                     87: #endif AED
                     88: 
                     89: #ifdef TRACE_X
                     90:         fprintf(stderr, "In SinglePixelLine\n");
                     91:         fflush(stderr);
                     92: #endif TRACE_X
                     93: 
                     94:        /*
                     95:         * Clip line. If nothing to draw after clip
                     96:         * return to caller.
                     97:         */
                     98: 
                     99:        ClipLine(StartX, StartY, StopX, StopY, Clip);
                    100: 
                    101:        /*
                    102:         * Always draw left to right
                    103:         */
                    104: 
                    105:        if (StopX < StartX) {
                    106:            Temp = StopX,  StopX = StartX,  StartX = Temp;
                    107:            Temp = StopY,  StopY = StartY,  StartY = Temp;
                    108:        }
                    109: 
                    110:        /*
                    111:         * Compute delta values and bitmap width in shorts
                    112:         */
                    113: 
                    114:        DeltaX = StopX - StartX;
                    115:        DeltaY = StopY - StartY;
                    116: 
                    117:        NumberOfShorts = (BitMap->width + 15) / 16;
                    118: 
                    119: #if (defined(APA8) || defined(APA8C))
                    120:        if (DeltaY > 0) {       /* drawing top to bottom */
                    121:            if (BitMap == SCREEN_BITMAP)
                    122:                NumberOfBytes = NumberOfShorts << 2;
                    123:            else
                    124:                NumberOfBytes = NumberOfShorts << 1;
                    125:        } else {                /* drawing bottom to top */
                    126:            if (BitMap == SCREEN_BITMAP)
                    127:                NumberOfBytes = -(NumberOfShorts << 2);
                    128:            else
                    129:                NumberOfBytes = -(NumberOfShorts << 1);
                    130:            DeltaY = -DeltaY;
                    131:        }
                    132: #else
                    133:        if (DeltaY > 0) {       /* drawing top to bottom */
                    134:            NumberOfBytes = NumberOfShorts << 1;
                    135:        } else {                /* drawing bottom to top */
                    136:            NumberOfBytes = -(NumberOfShorts << 1);
                    137:            DeltaY = -DeltaY;
                    138:        }
                    139: #endif (APA8 || APA8C)
                    140: 
                    141:        /*
                    142:         * Get source and alternate tiles
                    143:         */
                    144: 
                    145:        Source = *ConstantTiles[SrcPix & 1];
                    146:        if(Mode == DrawPatternedLine)
                    147:                AltSource = *ConstantTiles[AltPix & 1];
                    148: 
                    149:        /*
                    150:         * Compute starting destination address
                    151:         */
                    152: 
                    153: #if (defined(APA8) || defined (APA8C))
                    154:        if (BitMap == SCREEN_BITMAP) {
                    155:            Destination = (u_short *) BitMap->data +
                    156:                        ((StartX / 16 + StartY * NumberOfShorts) << 1);
                    157:            DestinationIncrement = 4;
                    158:        } else {
                    159:            Destination = (u_short *) BitMap->data +
                    160:                        StartX / 16 + StartY * NumberOfShorts;
                    161:            DestinationIncrement = 2;
                    162:        }
                    163: #else
                    164:        Destination = (u_short *) BitMap->data +
                    165:                        StartX / 16 + StartY * NumberOfShorts;
                    166: #endif (APA8 || APA8C)
                    167: 
                    168:        /*
                    169:         * set mask to select starting bit
                    170:         */
                    171: 
                    172:        MaskBit = 0x8000 >> (StartX & 0x0F);
                    173: 
                    174:        /*
                    175:         * If this is not a solid line setup pattern values
                    176:         */
                    177: 
                    178:        if (Mode != DrawSolidLine) {
                    179:                RepeatCount = PatternMultiplier;
                    180:                PatternFirstBit = 1 << (PatternLength - 1);
                    181:                PatternBit = PatternFirstBit;
                    182:        }
                    183: 
                    184: #ifdef SOFTWARE_CURSOR
                    185:        /*
                    186:         * Save cursor if blt is to screen
                    187:         */
                    188: 
                    189:        if (BitMap == SCREEN_BITMAP) {
                    190:                if (save_cursor(MIN(StopX, StartX), MIN(StopY, StartY),
                    191:                     MAX(StopX, StartX) + 1, MAX(StopY, StartY) + 1) < 0)
                    192:                {
                    193:                        DeviceError(
                    194:                            "SinglePixelLine: ioctl QIOCHIDECUR failed.\n"
                    195:                        );
                    196:                }
                    197:        }
                    198: #endif SOFTWARE_CURSOR
                    199: 
                    200:        /*
                    201:         * draw the line
                    202:         */
                    203: 
                    204:        if (DeltaX > DeltaY) {  /* This is a horizontal line */
                    205:            Sentinel = DeltaX >> 1;
                    206:             BitsLeftToDraw = DeltaX;
                    207: 
                    208:            switch (Rule) {
                    209:            case (GXor):
                    210:                    HORIZONTAL_LINE (
                    211:                        {*Destination |= (Source & MaskBit);},
                    212:                        {*Destination |= (AltSource & MaskBit);}
                    213:                    );
                    214:                    break;
                    215:            case (GXcopy):
                    216:                    HORIZONTAL_LINE (
                    217:                        {*Destination = (*Destination & ~MaskBit) |
                    218:                                (Source & MaskBit);},
                    219:                        {*Destination = (*Destination & ~MaskBit) |
                    220:                                (AltSource & MaskBit);}
                    221:                    );
                    222:                    break;
                    223:            case (GXxor):
                    224:                    HORIZONTAL_LINE (
                    225:                        {*Destination ^= (Source & MaskBit);},
                    226:                        {*Destination ^= (AltSource & MaskBit);}
                    227:                    );
                    228:                    break;
                    229:            case (GXset):
                    230:                    HORIZONTAL_LINE (
                    231:                        {*Destination |= MaskBit;},
                    232:                        {*Destination |= MaskBit;}
                    233:                    );
                    234:                    break;
                    235:            case (GXclear):
                    236:                    HORIZONTAL_LINE (
                    237:                        {*Destination &= ~MaskBit;},
                    238:                        {*Destination &= ~MaskBit;}
                    239:                    );
                    240:                    break;
                    241:            case (GXinvert):
                    242:                    HORIZONTAL_LINE (
                    243:                        {*Destination ^= MaskBit;},
                    244:                        {*Destination ^= MaskBit;}
                    245:                    );
                    246:                    break;
                    247:            case (GXcopyInverted):
                    248:                    HORIZONTAL_LINE (
                    249:                        {*Destination = (*Destination & ~MaskBit) |
                    250:                                (~Source & MaskBit);},
                    251:                        {*Destination = (*Destination & ~MaskBit) |
                    252:                                (~AltSource & MaskBit);}
                    253:                    );
                    254:                    break;
                    255:            case (GXandInverted):
                    256:                    HORIZONTAL_LINE (
                    257:                        {*Destination &= ~(Source & MaskBit);},
                    258:                        {*Destination &= ~(AltSource & MaskBit);}
                    259:                    );
                    260:                    break;
                    261:            case (GXorReverse):
                    262:                    HORIZONTAL_LINE (
                    263:                        {*Destination = (*Destination & ~MaskBit) |
                    264:                                ((~*Destination | Source) & MaskBit);},
                    265:                        {*Destination = (*Destination & ~MaskBit) |
                    266:                                ((~*Destination | AltSource) & MaskBit);}
                    267:                    );
                    268:                    break;
                    269:            case (GXequiv):
                    270:                    HORIZONTAL_LINE (
                    271:                        {*Destination = (*Destination & ~MaskBit) |
                    272:                                ((*Destination ^ ~Source) & MaskBit);},
                    273:                        {*Destination = (*Destination & ~MaskBit) |
                    274:                                ((*Destination ^ ~AltSource) & MaskBit);}
                    275:                    );
                    276:                    break;
                    277:            case (GXnand):
                    278:                    HORIZONTAL_LINE (
                    279:                        {*Destination = (*Destination & ~MaskBit) |
                    280:                                ((~*Destination | ~Source) & MaskBit);},
                    281:                        {*Destination = (*Destination & ~MaskBit) |
                    282:                                ((~*Destination | ~AltSource) & MaskBit);}
                    283:                    );
                    284:                    break;
                    285:            case (GXnor):
                    286:                    HORIZONTAL_LINE (
                    287:                        {*Destination = (*Destination & ~MaskBit) |
                    288:                                ((~*Destination & ~Source) & MaskBit);},
                    289:                        {*Destination = (*Destination & ~MaskBit) |
                    290:                                ((~*Destination & ~AltSource) & MaskBit);}
                    291:                    );
                    292:                    break;
                    293:            case (GXandReverse):
                    294:                    HORIZONTAL_LINE (
                    295:                        {*Destination = (*Destination & ~MaskBit) |
                    296:                                ((~*Destination & Source) & MaskBit);},
                    297:                        {*Destination = (*Destination & ~MaskBit) |
                    298:                                ((~*Destination & AltSource) & MaskBit);}
                    299:                    );
                    300:                    break;
                    301:            case (GXand):
                    302:                    HORIZONTAL_LINE (
                    303:                        {*Destination = (*Destination & ~MaskBit) |
                    304:                                ((*Destination & Source) & MaskBit);},
                    305:                        {*Destination = (*Destination & ~MaskBit) |
                    306:                                ((*Destination & AltSource) & MaskBit);}
                    307:                    );
                    308:                    break;
                    309:            case (GXorInverted):
                    310:                    HORIZONTAL_LINE (
                    311:                        {*Destination = (*Destination & ~MaskBit) |
                    312:                                ((*Destination | ~Source) & MaskBit);},
                    313:                        {*Destination = (*Destination & ~MaskBit) |
                    314:                                ((*Destination | ~AltSource) & MaskBit);}
                    315:                    );
                    316:            }
                    317:        } else {        /* This is a vertical line */
                    318:            Sentinel = DeltaY >> 1;
                    319:             BitsLeftToDraw = DeltaY;
                    320: 
                    321:            switch (Rule) {
                    322:            case (GXor):
                    323:                    VERTICAL_LINE (
                    324:                        {*Destination |= (Source & MaskBit);},
                    325:                        {*Destination |= (AltSource & MaskBit);}
                    326:                    );
                    327:                    break;
                    328:            case (GXcopy):
                    329:                    VERTICAL_LINE (
                    330:                        {*Destination = (*Destination & ~MaskBit) |
                    331:                                (Source & MaskBit);},
                    332:                        {*Destination = (*Destination & ~MaskBit) |
                    333:                                (AltSource & MaskBit);}
                    334:                    );
                    335:                    break;
                    336:            case (GXxor):
                    337:                    VERTICAL_LINE (
                    338:                        {*Destination ^= (Source & MaskBit);},
                    339:                        {*Destination ^= (AltSource & MaskBit);}
                    340:                    );
                    341:                    break;
                    342:            case (GXset):
                    343:                    VERTICAL_LINE (
                    344:                        {*Destination |= MaskBit;},
                    345:                        {*Destination |= MaskBit;}
                    346:                    );
                    347:                    break;
                    348:            case (GXclear):
                    349:                    VERTICAL_LINE(
                    350:                        {*Destination &= ~MaskBit;},
                    351:                        {*Destination &= ~MaskBit;}
                    352:                    );
                    353:                    break;
                    354:            case (GXinvert):
                    355:                    VERTICAL_LINE (
                    356:                        {*Destination ^= MaskBit;},
                    357:                        {*Destination ^= MaskBit;}
                    358:                    );
                    359:                    break;
                    360:            case (GXcopyInverted):
                    361:                    VERTICAL_LINE (
                    362:                        {*Destination = (*Destination & ~MaskBit) |
                    363:                                (~Source & MaskBit);},
                    364:                        {*Destination = (*Destination & ~MaskBit) |
                    365:                                (~AltSource & MaskBit);}
                    366:                    );
                    367:                    break;
                    368:            case (GXandInverted):
                    369:                    VERTICAL_LINE (
                    370:                        {*Destination &= ~(Source & MaskBit);},
                    371:                        {*Destination &= ~(AltSource & MaskBit);}
                    372:                    );
                    373:                    break;
                    374:            case (GXorReverse):
                    375:                    VERTICAL_LINE (
                    376:                        {*Destination = (*Destination & ~MaskBit) |
                    377:                                ((~*Destination | Source) & MaskBit);},
                    378:                        {*Destination = (*Destination & ~MaskBit) |
                    379:                                ((~*Destination | AltSource) & MaskBit);}
                    380:                    );
                    381:                    break;
                    382:            case (GXequiv):
                    383:                    VERTICAL_LINE (
                    384:                        {*Destination = (*Destination & ~MaskBit) |
                    385:                                ((*Destination ^ ~Source) & MaskBit);},
                    386:                        {*Destination = (*Destination & ~MaskBit) |
                    387:                                ((*Destination ^ ~AltSource) & MaskBit);}
                    388:                    );
                    389:                    break;
                    390:            case (GXnand):
                    391:                    VERTICAL_LINE (
                    392:                        {*Destination = (*Destination & ~MaskBit) |
                    393:                                ((~*Destination | ~Source) & MaskBit);},
                    394:                        {*Destination = (*Destination & ~MaskBit) |
                    395:                                ((~*Destination | ~AltSource) & MaskBit);}
                    396:                    );
                    397:                    break;
                    398:            case (GXnor):
                    399:                    VERTICAL_LINE (
                    400:                        {*Destination = (*Destination & ~MaskBit) |
                    401:                                ((~*Destination & ~Source) & MaskBit);},
                    402:                        {*Destination = (*Destination & ~MaskBit) |
                    403:                                ((~*Destination & ~AltSource) & MaskBit);}
                    404:                    );
                    405:                    break;
                    406:            case (GXandReverse):
                    407:                    VERTICAL_LINE (
                    408:                        {*Destination = (*Destination & ~MaskBit) |
                    409:                                ((~*Destination & Source) & MaskBit);},
                    410:                        {*Destination = (*Destination & ~MaskBit) |
                    411:                                ((~*Destination & AltSource) & MaskBit);}
                    412:                    );
                    413:                    break;
                    414:            case (GXand):
                    415:                    VERTICAL_LINE (
                    416:                        {*Destination = (*Destination & ~MaskBit) |
                    417:                                ((*Destination & Source) & MaskBit);},
                    418:                        {*Destination = (*Destination & ~MaskBit) |
                    419:                                ((*Destination & AltSource) & MaskBit);}
                    420:                    );
                    421:                    break;
                    422:            case (GXorInverted):
                    423:                    VERTICAL_LINE (
                    424:                        {*Destination = (*Destination & ~MaskBit) |
                    425:                                ((*Destination | ~Source) & MaskBit);},
                    426:                        {*Destination = (*Destination & ~MaskBit) |
                    427:                                ((*Destination | ~AltSource) & MaskBit);}
                    428:                    );
                    429:            }
                    430:        }
                    431: 
                    432: #ifdef SOFTWARE_CURSOR
                    433:        /*
                    434:         * Restore cursor to screen
                    435:         */
                    436: 
                    437:        if (BitMap == SCREEN_BITMAP) {
                    438:            if (restore_cursor() < 0) {
                    439:                    DeviceError("SinglePixelLine: ioctl QIOCSHOWCUR failed.\n");
                    440:            }
                    441:        }
                    442: #endif SOFTWARE_CURSOR
                    443: 
                    444: #ifdef AED
                    445:        /*
                    446:         * Unable to use microcode to draw the line.
                    447:         * Therefore, it must be echoed to the
                    448:         * AED screen to become visible.
                    449:         */
                    450: 
                    451:        if (EchoLine) {
                    452:            changed_rect.origin_y = MIN(StopY, StartY);
                    453:             changed_rect.origin_x = MIN(StopX, StartX);
                    454:             changed_rect.corner_y = MAX(StopY, StartY) + 1;
                    455:             changed_rect.corner_x = MAX(StopX, StartX) + 1;
                    456:            aed_echo_rect(&changed_rect);
                    457:        }
                    458: #endif AED
                    459: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.