Annotation of 43BSDTahoe/new/X/libibm/libsrc/spixline.c, revision 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.