📄 cfb8line.c
字号:
/* * $XConsortium: cfb8line.c,v 1.19 91/07/09 16:07:32 rws Exp $ * * Copyright 1990 Massachusetts Institute of Technology * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, 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 M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Keith Packard, MIT X Consortium */#include "X.h"#include "gcstruct.h"#include "windowstr.h"#include "pixmapstr.h"#include "regionstr.h"#include "scrnintstr.h"#include "mistruct.h"#include "cfb.h"#include "cfbmskbits.h"#include "cfbrrop.h"#if defined(__GNUC__) && defined(mc68020)#define STUPID volatile#define REARRANGE#else#define STUPID#endif#ifdef __GNUC__/* lame compiler doesn't even look at 'register' attributes */#define I_H do{#define I_T }while(0);#define IMPORTANT_START I_H I_H I_H I_H I_H I_H I_H I_H I_H I_H#define IMPORTANT_END I_T I_T I_T I_T I_T I_T I_T I_T I_T I_T#else#define IMPORTANT_START#define IMPORTANT_END#endif#define OUTCODES(result, x, y, box) \ if (x < box->x1) \ result |= OUT_LEFT; \ if (x >= box->x2) \ result |= OUT_RIGHT; \ if (y < box->y1) \ result |= OUT_ABOVE; \ if (y >= box->y2) \ result |= OUT_BELOW;#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & ClipMask)#ifdef POLYSEGMENT# ifdef sun# define WIDTH_FAST 1152# endif# ifdef ultrix# define WIDTH_FAST 1024# endif# ifdef Mips# define WIDTH_FAST 4096# endif# ifdef WIDTH_FAST# if WIDTH_FAST == 1024# define FAST_MUL(y) ((y) << 10)# endif# if WIDTH_FAST == 1152# define FAST_MUL(y) (((y) << 10) + ((y) << 7))# endif# if WIDTH_FAST == 1280# define FAST_MUL(y) (((y) << 10) + ((y) << 8))# endif# if WIDTH_FAST == 2048# define FAST_MUL(y) ((y) << 11)# endif# if WIDTH_FAST == 4096# define FAST_MUL(y) ((y) << 12)# endif# endif# if defined(WIDTH_SHIFT)# ifdef FAST_MUL# define FUNC_NAME(e) RROP_NAME(RROP_NAME_CAT(e,Shift))# if RROP == GXcopy# define INCLUDE_OTHERS# define SERIOUS_UNROLLING# endif# define INCLUDE_DRAW# define NWIDTH(nwidth) WIDTH_FAST# define WIDTH_MUL(y,w) FAST_MUL(y)# endif# else# define FUNC_NAME(e) RROP_NAME(e)# define WIDTH_MUL(y,w) ((y) * (w))# define NWIDTH(nwidth) (nwidth)# define INCLUDE_DRAW# if !defined (FAST_MUL) && RROP == GXcopy# define INCLUDE_OTHERS# define SERIOUS_UNROLLING# endif# endif#else# define INCLUDE_DRAW# define WIDTH_MUL(y,w) ((y) * (w))# define NWIDTH(nwidth) nwidth# ifdef PREVIOUS# define FUNC_NAME(e) RROP_NAME(RROP_NAME_CAT(e,Previous))# else# define FUNC_NAME(e) RROP_NAME(e)# if RROP == GXcopy# define INCLUDE_OTHERS# ifdef PLENTIFUL_REGISTERS# define SAVE_X2Y2# endif# define ORIGIN# define SERIOUS_UNROLLING# else# define EITHER_MODE# endif# endif#endif#ifdef INCLUDE_DRAWint#ifdef POLYSEGMENTFUNC_NAME(cfb8SegmentSS1Rect) (pDrawable, pGC, nseg, pSegInit) DrawablePtr pDrawable; GCPtr pGC; int nseg; xSegment *pSegInit;#elseFUNC_NAME(cfb8LineSS1Rect) (pDrawable, pGC, mode, npt, pptInit) DrawablePtr pDrawable; GCPtr pGC; int mode; /* Origin or Previous */ int npt; /* number of points */ DDXPointPtr pptInit;#endif{ register int e; register int y1_or_e1; register unsigned char *addrb; register int stepmajor; register int stepminor;#ifndef REARRANGE register int e3;#endif#ifdef mc68000 register short x1_or_len;#else register int x1_or_len;#endif RROP_DECLARE#ifdef SAVE_X2Y2# define c2 y2#else register int c2;#endif register int upperleft, lowerright;#ifdef POLYSEGMENT register int capStyle;#endif#ifdef SAVE_X2Y2 register int x2, y2;# define X1 x1_or_len# define Y1 y1_or_e1# define X2 x2# define Y2 y2#else# ifdef POLYSEGMENT# define X1 x1_or_len# define Y1 y1_or_e1# else# define X1 intToX(y1_or_e1)# define Y1 intToY(y1_or_e1)# endif# define X2 intToX(c2)# define Y2 intToY(c2)#endif unsigned long ClipMask = 0x80008000; unsigned char *addr; int nwidth; cfbPrivGCPtr devPriv; BoxPtr extents; int *ppt; devPriv = (cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr); cfbGetByteWidthAndPointer (pDrawable, nwidth, addr); SET_REGISTERS_FOR_WRITING(pDrawable->pScreen, ~0, GXcopy);#ifndef REARRANGE RROP_FETCH_GCPRIV(devPriv);#endif extents = &devPriv->pCompositeClip->extents; c2 = *((int *) &pDrawable->x); c2 -= (c2 & 0x8000) << 1; upperleft = *((int *) &extents->x1) - c2; lowerright = *((int *) &extents->x2) - c2 - 0x00010001; addr = addr + WIDTH_MUL(pDrawable->y,nwidth) + pDrawable->x;#ifdef POLYSEGMENT capStyle = pGC->capStyle - CapNotLast; ppt = (int *) pSegInit; while (nseg--)#else#ifdef EITHER_MODE mode -= CoordModePrevious;#endif ppt = (int *) pptInit; c2 = *ppt++; if (isClipped (c2, upperleft, lowerright)) {#ifndef ORIGIN#ifdef EITHER_MODE if (!mode)#endif { e = *ppt; *ppt = e + c2 - ((e & 0x8000) << 1); }#endif return 1; }#ifdef SAVE_X2Y2 intToCoord(c2,x2,y2);#endif addrb = addr + WIDTH_MUL(Y2, nwidth) + X2; while (--npt)#endif {#ifdef POLYSEGMENT y1_or_e1 = ppt[0]; c2 = ppt[1]; ppt += 2; if (isClipped(y1_or_e1,upperleft,lowerright)|isClipped(c2,upperleft,lowerright)) break; intToCoord(y1_or_e1,x1_or_len,y1_or_e1); /* compute now to avoid needing x1, y1 later */ addrb = addr + WIDTH_MUL(y1_or_e1, nwidth) + x1_or_len;#else#ifndef SAVE_X2Y2 y1_or_e1 = c2;#else y1_or_e1 = y2; x1_or_len = x2;#endif#ifndef ORIGIN e = c2; c2 = *ppt++;#ifdef EITHER_MODE if (!mode)#endif c2 = c2 + e - ((c2 & 0x8000) << 1);#else c2 = *ppt++;#endif if (isClipped (c2, upperleft, lowerright)) {#ifndef ORIGIN#ifdef EITHER_MODE if (!mode)#endif { ppt[-2] = e; ppt[-1] = c2; }#endif break; }#ifdef SAVE_X2Y2 intToCoord(c2,x2,y2);#endif#endif stepmajor = 1; if ((x1_or_len = X2 - X1) < 0) { x1_or_len = -x1_or_len; stepmajor = -1; } stepminor = NWIDTH(nwidth); if ((y1_or_e1 = Y2 - Y1) < 0) { y1_or_e1 = -y1_or_e1; stepminor = -stepminor; }#ifdef POLYSEGMENT /* * although the horizontal code works for polyline, it * slows down 10 pixel lines by 15%. Thus, this * code is optimized for horizontal segments and * random orientation lines, which seems like a reasonable * assumption */ if (y1_or_e1 != 0) {#endif if (x1_or_len < y1_or_e1) {#ifdef REARRANGE register int e3;#endif e3 = x1_or_len; x1_or_len = y1_or_e1; y1_or_e1 = e3; e3 = stepminor; stepminor = stepmajor; stepmajor = e3; } e = -x1_or_len;#ifdef POLYSEGMENT if (!capStyle) x1_or_len--;#endif {#ifdef REARRANGE register int e3; RROP_DECLARE RROP_FETCH_GCPRIV(devPriv);#endif y1_or_e1 = y1_or_e1 << 1; e3 = e << 1;#define body {\ RROP_SOLID(addrb); \ addrb += stepmajor; \ e += y1_or_e1; \ if (e >= 0) \ { \ addrb += stepminor; \ e += e3; \ } \ }#ifdef LARGE_INSTRUCTION_CACHE# ifdef SERIOUS_UNROLLING# define UNROLL 16# else# define UNROLL 4# endif# define CASE(n) case -n: body while ((x1_or_len -= UNROLL) >= 0) { body body body body# if UNROLL >= 8 body body body body# endif# if UNROLL >= 12 body body body body# endif# if UNROLL >= 16 body body body body# endif } switch (x1_or_len) { CASE(1) CASE(2) CASE(3)# if UNROLL >= 8 CASE(4) CASE(5) CASE(6) CASE(7)# endif# if UNROLL >= 12 CASE(8) CASE(9) CASE(10) CASE(11)# endif# if UNROLL >= 16 CASE(12) CASE(13) CASE(14) CASE(15)# endif }#else IMPORTANT_START IMPORTANT_START if (x1_or_len & 1) body x1_or_len >>= 1; while (x1_or_len--) { body body } IMPORTANT_END IMPORTANT_END#endif#ifdef POLYSEGMENT RROP_SOLID(addrb);#endif }#undef body#ifdef POLYSEGMENT } else {# ifndef POLYSEGMENT unsigned char *t;#endif# ifdef REARRANGE register int e3; RROP_DECLARE RROP_FETCH_GCPRIV(devPriv);# endif if (stepmajor < 0) { addrb -= x1_or_len;# ifndef POLYSEGMENT t = addrb;# else if (capStyle) x1_or_len++; else# endif addrb++; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -